diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt index 40d4a4de6..20bf1f974 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt @@ -44,8 +44,15 @@ class MusicViewModel : ViewModel(), Indexer.Callback { indexer.registerCallback(this) } + /** + * Re-index the music library. + */ fun reindex() { - indexer.requestReindex() + indexer.requestReindex(true) + } + + fun rescan() { + indexer.requestReindex(false) } override fun onIndexerStateChanged(state: Indexer.State?) { diff --git a/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheExtractor.kt b/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheExtractor.kt index 4fef918b9..52225fa45 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheExtractor.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheExtractor.kt @@ -38,11 +38,15 @@ import java.io.File * modification times for files, as these are required for the cache to function well. * @author OxygenCobalt */ -class CacheExtractor(private val context: Context) { +class CacheExtractor(private val context: Context, private val noop: Boolean) { private var cacheMap: Map? = null - private var shouldWriteCache = false + private var shouldWriteCache = noop fun init() { + if (noop) { + return + } + try { cacheMap = CacheDatabase.getInstance(context).read() } catch (e: Exception) { diff --git a/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt b/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt index 7ad50fc01..b55a2a24e 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt @@ -24,7 +24,6 @@ import android.os.Build import androidx.core.content.ContextCompat import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay import kotlinx.coroutines.withContext import kotlinx.coroutines.yield import org.oxycblt.auxio.BuildConfig @@ -134,8 +133,9 @@ class Indexer { /** * Start the indexing process. This should be done by [Controller] in a background thread. When * complete, a new completion state will be pushed to each callback. + * @param fresh Whether to use the cache when loading. */ - suspend fun index(context: Context) { + suspend fun index(context: Context, fresh: Boolean) { val notGranted = ContextCompat.checkSelfPermission(context, PERMISSION_READ_AUDIO) == PackageManager.PERMISSION_DENIED @@ -148,7 +148,7 @@ class Indexer { val response = try { val start = System.currentTimeMillis() - val library = indexImpl(context) + val library = indexImpl(context, fresh) if (library != null) { logD( "Music indexing completed successfully in " + @@ -175,11 +175,12 @@ class Indexer { /** * Request that re-indexing should be done. This should be used by components that do not manage * the indexing process to re-index music. + * @param withCache Whether to use the cache when loading music. */ @Synchronized - fun requestReindex() { + fun requestReindex(withCache: Boolean) { logD("Requesting reindex") - controller?.onStartIndexing() + controller?.onStartIndexing(withCache) } /** @@ -196,13 +197,13 @@ class Indexer { /** * Run the proper music loading process. */ - private suspend fun indexImpl(context: Context): MusicStore.Library? { + private suspend fun indexImpl(context: Context, withCache: Boolean): MusicStore.Library? { // Create the chain of extractors. Each extractor builds on the previous and // enables version-specific features in order to create the best possible music // experience. This is technically dependency injection. Except it doesn't increase // your compile times by 3x. Isn't that nice. - val cacheDatabase = CacheExtractor(context) + val cacheDatabase = CacheExtractor(context, !withCache) val mediaStoreExtractor = when { @@ -434,7 +435,7 @@ class Indexer { } interface Controller : Callback { - fun onStartIndexing() + fun onStartIndexing(withCache: Boolean) } companion object { diff --git a/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt b/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt index 3cd1ac636..3478e53f3 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt @@ -89,7 +89,7 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback { indexer.registerController(this) if (musicStore.library == null && indexer.isIndeterminate) { logD("No library present and no previous response, indexing music now") - onStartIndexing() + onStartIndexing(true) } logD("Service created.") @@ -117,13 +117,13 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback { // --- CONTROLLER CALLBACKS --- - override fun onStartIndexing() { + override fun onStartIndexing(withCache: Boolean) { if (indexer.isIndexing) { currentIndexJob?.cancel() indexer.cancelLast() } - currentIndexJob = indexScope.launch { indexer.index(this@IndexerService) } + currentIndexJob = indexScope.launch { indexer.index(this@IndexerService, withCache) } } override fun onIndexerStateChanged(state: Indexer.State?) { @@ -228,7 +228,7 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback { getString(R.string.set_key_exclude_non_music), getString(R.string.set_key_music_dirs), getString(R.string.set_key_music_dirs_include), - getString(R.string.set_key_separators) -> onStartIndexing() + getString(R.string.set_key_separators) -> onStartIndexing(true) getString(R.string.set_key_observing) -> { if (!indexer.isIndexing) { updateIdleSession() @@ -263,7 +263,8 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback { // Check here if we should even start a reindex. This is much less bug-prone than // registering and de-registering this component as this setting changes. if (settings.shouldBeObserving) { - onStartIndexing() + onSt + artIndexing(true) } } } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/prefs/PreferenceFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/prefs/PreferenceFragment.kt index a6bc91045..bb2616889 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/prefs/PreferenceFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/prefs/PreferenceFragment.kt @@ -145,6 +145,9 @@ class PreferenceFragment : PreferenceFragmentCompat() { context.getString(R.string.set_key_reindex) -> { musicModel.reindex() } + context.getString(R.string.set_key_rescan) -> { + musicModel.rescan() + } else -> return super.onPreferenceTreeClick(preference) } diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml index ddf4e68da..a794fe77f 100644 --- a/app/src/main/res/values/settings.xml +++ b/app/src/main/res/values/settings.xml @@ -6,6 +6,7 @@ auxio_accent2 auxio_reindex + auxio_rescan auxio_observing auxio_music_dirs auxio_cover_mode diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c31654e1..596877463 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -218,9 +218,12 @@ Content Reload music - May wipe playback state + Reload the music library, using the cache whenever possible + + Rescan music + Reload the music library and re-create the cache (Slower, but more complete) Automatic reloading - Reload your music library whenever it changes (Requires persistent notification) + Reload the music library whenever it changes (Requires persistent notification) Music folders Manage where music should be loaded from diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 2f615cc2c..b7d9ce354 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -139,6 +139,10 @@ app:key="@string/set_key_reindex" app:summary="@string/set_reindex_desc" app:title="@string/set_reindex" /> +