diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/AutoMediaBrowserCallback.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/AutoMediaBrowserCallback.kt index 85863490..12761b93 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/AutoMediaBrowserCallback.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/AutoMediaBrowserCallback.kt @@ -34,7 +34,6 @@ import com.google.common.collect.ImmutableList import com.google.common.util.concurrent.FutureCallback import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture -import com.google.common.util.concurrent.MoreExecutors import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -52,6 +51,7 @@ import org.moire.ultrasonic.domain.SearchResult import org.moire.ultrasonic.domain.Track import org.moire.ultrasonic.service.MediaPlayerController import org.moire.ultrasonic.service.MusicServiceFactory +import org.moire.ultrasonic.util.MainThreadExecutor import org.moire.ultrasonic.util.Settings import org.moire.ultrasonic.util.Util import timber.log.Timber @@ -98,7 +98,7 @@ const val SESSION_CUSTOM_SET_RATING = "SESSION_CUSTOM_SET_RATING" * MediaBrowserService implementation for e.g. Android Auto */ @Suppress("TooManyFunctions", "LargeClass", "UnusedPrivateMember") -class AutoMediaBrowserCallback(var player: Player) : +class AutoMediaBrowserCallback(var player: Player, val libraryService: MediaLibraryService) : MediaLibraryService.MediaLibrarySession.Callback, KoinComponent { private val mediaPlayerController by inject() @@ -234,7 +234,8 @@ class AutoMediaBrowserCallback(var player: Player) : object : FutureCallback { override fun onSuccess(result: SessionResult) { track.starred = !track.starred - // Handle notification reload here + // This needs to be called on the main Thread + libraryService.onUpdateNotification(session) } override fun onFailure(t: Throwable) { @@ -245,7 +246,7 @@ class AutoMediaBrowserCallback(var player: Player) : ).show() } }, - MoreExecutors.directExecutor() + MainThreadExecutor() ) } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/PlaybackService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/PlaybackService.kt index 1cc994d2..3cb043dd 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/PlaybackService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/playback/PlaybackService.kt @@ -111,7 +111,7 @@ class PlaybackService : MediaLibraryService(), KoinComponent { player.experimentalSetOffloadSchedulingEnabled(true) // Create browser interface - librarySessionCallback = AutoMediaBrowserCallback(player) + librarySessionCallback = AutoMediaBrowserCallback(player, this) // This will need to use the AutoCalls mediaLibrarySession = MediaLibrarySession.Builder(this, player, librarySessionCallback) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/MainThreadExecutor.java b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/MainThreadExecutor.java new file mode 100644 index 00000000..12c1ae55 --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/MainThreadExecutor.java @@ -0,0 +1,26 @@ +/* + * MainThreadExecutor.java + * Copyright (C) 2009-2022 Ultrasonic developers + * + * Distributed under terms of the GNU GPLv3 license. + */ + +package org.moire.ultrasonic.util; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.Executor; + +/* +* Executor for running Futures on the main thread +* See https://stackoverflow.com/questions/52642246/how-to-get-executor-for-main-thread-on-api-level-28 +*/ +public class MainThreadExecutor implements Executor { + private final Handler handler = new Handler(Looper.getMainLooper()); + + @Override + public void execute(Runnable r) { + handler.post(r); + } +}