From 1b40e700583ef78895898f79a578ef18776dda31 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 24 Mar 2025 17:33:53 -0400 Subject: [PATCH] Fixing the Notification order for multiple playbacks --- .../service/playback/pip/BackgroundMedia.kt | 2 +- .../playback/playerPool/MediaSessionPool.kt | 2 + .../playback/service/PlaybackService.kt | 44 ++++++++++++------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/pip/BackgroundMedia.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/pip/BackgroundMedia.kt index 0b471daf8..a2aaabdd8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/pip/BackgroundMedia.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/pip/BackgroundMedia.kt @@ -48,7 +48,7 @@ object BackgroundMedia { // background playing mutex. val bgInstance = MutableStateFlow(null) - private fun hasInstance() = bgInstance.value != null + fun hasInstance() = bgInstance.value != null fun isPlaying() = bgInstance.value?.isPlaying() == true diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/MediaSessionPool.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/MediaSessionPool.kt index 8c3336473..e84cfff7a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/MediaSessionPool.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/MediaSessionPool.kt @@ -165,6 +165,8 @@ class MediaSessionPool( fun playingContent() = playingMap.values + fun getSession(id: String) = cache.get(id)?.session + class MediaSessionCallback( val pool: MediaSessionPool, ) : MediaSession.Callback { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/service/PlaybackService.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/service/PlaybackService.kt index 907a2558f..0f0f5dfb7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/service/PlaybackService.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/service/PlaybackService.kt @@ -29,6 +29,7 @@ import androidx.media3.exoplayer.ExoPlayer import androidx.media3.session.MediaSession import androidx.media3.session.MediaSessionService import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager +import com.vitorpamplona.amethyst.service.playback.pip.BackgroundMedia import com.vitorpamplona.amethyst.service.playback.playerPool.ExoPlayerBuilder import com.vitorpamplona.amethyst.service.playback.playerPool.ExoPlayerPool import com.vitorpamplona.amethyst.service.playback.playerPool.MediaSessionPool @@ -91,37 +92,46 @@ class PlaybackService : MediaSessionService() { // Updates any new player ready super.onUpdateNotification(session, startInForegroundRequired) - val proxyPlaying = poolWithProxy?.playingContent() + // playback controllers control the last notification updated. + // this procedure re-updates the notification to make sure it aligns + // with users expectation on which playback they decide to control: + // 1. If no video is being played, play the picture in picture if there. + // 2. If there are videos being played the order is: + // 2. a. Picture in picture if playing + // 2. b. On screen video with volume on + // 2. c. On screen video with volume off. - // Overrides the notification with any player actually playing - proxyPlaying?.forEach { - if (it.session.player.isPlaying) { + val playing = (poolWithProxy?.playingContent() ?: emptyList()) + (poolNoProxy?.playingContent() ?: emptyList()) + + // if nothing is pl + if (playing.isEmpty() && BackgroundMedia.hasInstance()) { + BackgroundMedia.bgInstance.value?.id?.let { id -> + (poolNoProxy?.getSession(id) ?: poolWithProxy?.getSession(id))?.let { + super.onUpdateNotification(it, startInForegroundRequired) + } + } + return + } + + playing.forEachIndexed { idx, it -> + if (it.session.player.isPlaying && it.session.player.volume > 0 && it.session.id == BackgroundMedia.bgInstance.value?.id) { super.onUpdateNotification(it.session, startInForegroundRequired) + return } } - // Overrides again with playing with audio - proxyPlaying?.forEach { + playing.forEachIndexed { idx, it -> if (it.session.player.isPlaying && it.session.player.volume > 0) { super.onUpdateNotification(it.session, startInForegroundRequired) + return } } - val noProxyPlaying = poolNoProxy?.playingContent() - - // Overrides the notification with any player actually playing - noProxyPlaying?.forEach { + playing.forEachIndexed { idx, it -> if (it.session.player.isPlaying) { super.onUpdateNotification(it.session, startInForegroundRequired) } } - - // Overrides again with playing with audio - noProxyPlaying?.forEach { - if (it.session.player.isPlaying && it.session.player.volume > 0) { - super.onUpdateNotification(it.session, startInForegroundRequired) - } - } } // Return a MediaSession to link with the MediaController that is making