music: try to fix repo race conditions
Forgot to slather the entire class in Synchronized and Volatile. Should make crashes less likely, I hope.
This commit is contained in:
parent
049d2bc152
commit
8953f12a1e
3 changed files with 27 additions and 28 deletions
|
@ -51,6 +51,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
* TODO: Fix UID naming
|
* TODO: Fix UID naming
|
||||||
* TODO: Leverage FlexibleListAdapter more in dialogs (Disable item anims)
|
* TODO: Leverage FlexibleListAdapter more in dialogs (Disable item anims)
|
||||||
* TODO: Add more logging
|
* TODO: Add more logging
|
||||||
|
* TODO: Try to move on from shared objs in synchronized and volatile
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
|
@ -26,6 +26,8 @@ import org.oxycblt.auxio.util.logE
|
||||||
*
|
*
|
||||||
* @param mode The type of list in the home view this instance corresponds to.
|
* @param mode The type of list in the home view this instance corresponds to.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
|
*
|
||||||
|
* TODO: Tab migration to playlists is busted and resets the config entirely. Need to fix.
|
||||||
*/
|
*/
|
||||||
sealed class Tab(open val mode: MusicMode) {
|
sealed class Tab(open val mode: MusicMode) {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -219,12 +219,12 @@ constructor(
|
||||||
) : MusicRepository {
|
) : MusicRepository {
|
||||||
private val updateListeners = mutableListOf<MusicRepository.UpdateListener>()
|
private val updateListeners = mutableListOf<MusicRepository.UpdateListener>()
|
||||||
private val indexingListeners = mutableListOf<MusicRepository.IndexingListener>()
|
private val indexingListeners = mutableListOf<MusicRepository.IndexingListener>()
|
||||||
private var indexingWorker: MusicRepository.IndexingWorker? = null
|
@Volatile private var indexingWorker: MusicRepository.IndexingWorker? = null
|
||||||
|
|
||||||
override var deviceLibrary: DeviceLibrary? = null
|
@Volatile override var deviceLibrary: DeviceLibrary? = null
|
||||||
override var userLibrary: MutableUserLibrary? = null
|
@Volatile override var userLibrary: MutableUserLibrary? = null
|
||||||
private var previousCompletedState: IndexingState.Completed? = null
|
@Volatile private var previousCompletedState: IndexingState.Completed? = null
|
||||||
private var currentIndexingState: IndexingState? = null
|
@Volatile private var currentIndexingState: IndexingState? = null
|
||||||
override val indexingState: IndexingState?
|
override val indexingState: IndexingState?
|
||||||
get() = currentIndexingState ?: previousCompletedState
|
get() = currentIndexingState ?: previousCompletedState
|
||||||
|
|
||||||
|
@ -272,55 +272,50 @@ constructor(
|
||||||
currentIndexingState = null
|
currentIndexingState = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
override fun find(uid: Music.UID) =
|
override fun find(uid: Music.UID) =
|
||||||
(deviceLibrary?.run { findSong(uid) ?: findAlbum(uid) ?: findArtist(uid) ?: findGenre(uid) }
|
(deviceLibrary?.run { findSong(uid) ?: findAlbum(uid) ?: findArtist(uid) ?: findGenre(uid) }
|
||||||
?: userLibrary?.findPlaylist(uid))
|
?: userLibrary?.findPlaylist(uid))
|
||||||
|
|
||||||
override suspend fun createPlaylist(name: String, songs: List<Song>) {
|
override suspend fun createPlaylist(name: String, songs: List<Song>) {
|
||||||
val userLibrary = userLibrary ?: return
|
val userLibrary = synchronized(this) { userLibrary ?: return }
|
||||||
userLibrary.createPlaylist(name, songs)
|
userLibrary.createPlaylist(name, songs)
|
||||||
for (listener in updateListeners) {
|
notifyUserLibraryChange()
|
||||||
listener.onMusicChanges(
|
|
||||||
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun renamePlaylist(playlist: Playlist, name: String) {
|
override suspend fun renamePlaylist(playlist: Playlist, name: String) {
|
||||||
val userLibrary = userLibrary ?: return
|
val userLibrary = synchronized(this) { userLibrary ?: return }
|
||||||
userLibrary.renamePlaylist(playlist, name)
|
userLibrary.renamePlaylist(playlist, name)
|
||||||
for (listener in updateListeners) {
|
notifyUserLibraryChange()
|
||||||
listener.onMusicChanges(
|
|
||||||
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deletePlaylist(playlist: Playlist) {
|
override suspend fun deletePlaylist(playlist: Playlist) {
|
||||||
val userLibrary = userLibrary ?: return
|
val userLibrary = synchronized(this) { userLibrary ?: return }
|
||||||
userLibrary.deletePlaylist(playlist)
|
userLibrary.deletePlaylist(playlist)
|
||||||
for (listener in updateListeners) {
|
notifyUserLibraryChange()
|
||||||
listener.onMusicChanges(
|
|
||||||
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
|
override suspend fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
|
||||||
val userLibrary = userLibrary ?: return
|
val userLibrary = synchronized(this) { userLibrary ?: return }
|
||||||
userLibrary.addToPlaylist(playlist, songs)
|
userLibrary.addToPlaylist(playlist, songs)
|
||||||
for (listener in updateListeners) {
|
notifyUserLibraryChange()
|
||||||
listener.onMusicChanges(
|
|
||||||
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>) {
|
override suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>) {
|
||||||
val userLibrary = userLibrary ?: return
|
val userLibrary = synchronized(this) { userLibrary ?: return }
|
||||||
userLibrary.rewritePlaylist(playlist, songs)
|
userLibrary.rewritePlaylist(playlist, songs)
|
||||||
|
notifyUserLibraryChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun notifyUserLibraryChange() {
|
||||||
for (listener in updateListeners) {
|
for (listener in updateListeners) {
|
||||||
listener.onMusicChanges(
|
listener.onMusicChanges(
|
||||||
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
override fun requestIndex(withCache: Boolean) {
|
override fun requestIndex(withCache: Boolean) {
|
||||||
indexingWorker?.requestIndex(withCache)
|
indexingWorker?.requestIndex(withCache)
|
||||||
}
|
}
|
||||||
|
@ -400,9 +395,10 @@ constructor(
|
||||||
throw NoMusicException()
|
throw NoMusicException()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Successfully loaded the library, now save the cache and create the library in
|
// Successfully loaded the library, now save the cache, create the library, and
|
||||||
// parallel.
|
// read playlist information in parallel.
|
||||||
logD("Discovered ${rawSongs.size} songs, starting finalization")
|
logD("Discovered ${rawSongs.size} songs, starting finalization")
|
||||||
|
// TODO: Indicate playlist state in loading process?
|
||||||
emitLoading(IndexingProgress.Indeterminate)
|
emitLoading(IndexingProgress.Indeterminate)
|
||||||
val deviceLibraryChannel = Channel<DeviceLibrary>()
|
val deviceLibraryChannel = Channel<DeviceLibrary>()
|
||||||
val deviceLibraryJob =
|
val deviceLibraryJob =
|
||||||
|
|
Loading…
Reference in a new issue