From 4f55a2a4a5441c458e4a14720ba0ca6bc2e83f30 Mon Sep 17 00:00:00 2001 From: birdbird <6892457-tzugen@users.noreply.gitlab.com> Date: Mon, 24 Jul 2023 18:57:29 +0000 Subject: [PATCH] Fix an exception when removeIncompleteTracksFromPlaylist() could be called on the wrong thread. --- .../ultrasonic/service/MediaPlayerManager.kt | 43 ++++++++++--------- .../org/moire/ultrasonic/service/RxBus.kt | 9 +--- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerManager.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerManager.kt index d1ffd067..2a4cbbdc 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerManager.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerManager.kt @@ -181,19 +181,22 @@ class MediaPlayerManager( createMediaController(onCreated) - rxBusSubscription += RxBus.activeServerChangingObservable.subscribe { oldServer -> - if (oldServer != OFFLINE_DB_ID) { - // When the server changes, the playlist can retain the downloaded songs. - // Incomplete songs should be removed as the new server won't recognise them. - removeIncompleteTracksFromPlaylist() - DownloadService.requestStop() + rxBusSubscription += RxBus.activeServerChangingObservable + // All interaction with the Media3 needs to happen on the main thread + .subscribeOn(RxBus.mainThread()) + .subscribe { oldServer -> + if (oldServer != OFFLINE_DB_ID) { + // When the server changes, the playlist can retain the downloaded songs. + // Incomplete songs should be removed as the new server won't recognise them. + removeIncompleteTracksFromPlaylist() + DownloadService.requestStop() + } + if (controller is JukeboxMediaPlayer) { + // When the server changes, the Jukebox should be released. + // The new server won't understand the jukebox requests of the old one. + switchToLocalPlayer() + } } - if (controller is JukeboxMediaPlayer) { - // When the server changes, the Jukebox should be released. - // The new server won't understand the jukebox requests of the old one. - switchToLocalPlayer() - } - } rxBusSubscription += RxBus.activeServerChangedObservable.subscribe { val jukebox = activeServerProvider.getActiveServer().jukeboxByDefault @@ -204,19 +207,19 @@ class MediaPlayerManager( isJukeboxEnabled = jukebox } - rxBusSubscription += RxBus.throttledPlaylistObservable.subscribe { - // Even though Rx should launch on the main thread it doesn't always :( - mainScope.launch { + rxBusSubscription += RxBus.throttledPlaylistObservable + // All interaction with the Media3 needs to happen on the main thread + .subscribeOn(RxBus.mainThread()) + .subscribe { serializeCurrentSession() } - } - rxBusSubscription += RxBus.throttledPlayerStateObservable.subscribe { - // Even though Rx should launch on the main thread it doesn't always :( - mainScope.launch { + rxBusSubscription += RxBus.throttledPlayerStateObservable + // All interaction with the Media3 needs to happen on the main thread + .subscribeOn(RxBus.mainThread()) + .subscribe { serializeCurrentSession() } - } rxBusSubscription += RxBus.shutdownCommandObservable.subscribe { clear(false) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RxBus.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RxBus.kt index 9c87c519..9912cf0d 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RxBus.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RxBus.kt @@ -1,8 +1,8 @@ package org.moire.ultrasonic.service -import android.os.Looper import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.core.Scheduler import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.subjects.PublishSubject @@ -12,14 +12,9 @@ import org.moire.ultrasonic.domain.Track class RxBus { - /* - * TODO: mainThread() seems to be not equal to the "normal" main Thread, so it causes - * a lot of often unnecessary thread switching. It looks like observeOn can actually - * be removed in many cases - */ companion object { - private fun mainThread() = AndroidSchedulers.from(Looper.getMainLooper()) + fun mainThread(): Scheduler = AndroidSchedulers.mainThread() val shufflePlayPublisher: PublishSubject = PublishSubject.create()