From 9aabfe22946e526128c2a8cc242024580bad7b08 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Thu, 3 Jun 2021 09:28:47 -0600 Subject: [PATCH] playback: make mediasession rely on exoplayer Make PlaybackSessionConnector also take events from ExoPlayer as it used to with MediaSessionConnector. This improves reliability somewhat at the cost of making the code even more hideous. --- .../playback/state/PlaybackStateManager.kt | 2 +- .../auxio/playback/system/PlaybackService.kt | 8 +++- .../system/PlaybackSessionConnector.kt | 37 ++++++++++++++----- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 0968173a5..266668aa2 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -234,8 +234,8 @@ class PlaybackStateManager private constructor() { private fun updatePlayback(song: Song, shouldPlay: Boolean = true) { mIsInUserQueue = false - mPosition = 0 mSong = song + mPosition = 0 setPlaying(shouldPlay) } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index 57e468bce..aeba83767 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -112,7 +112,7 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac isActive = true } - connector = PlaybackSessionConnector(this, mediaSession) + connector = PlaybackSessionConnector(this, player, mediaSession) // Then the notif/headset callbacks IntentFilter().apply { @@ -204,6 +204,12 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac playbackManager.next() } + override fun onPositionDiscontinuity(reason: Int) { + if (reason == Player.DISCONTINUITY_REASON_SEEK) { + playbackManager.setPosition(player.currentPosition) + } + } + // --- PLAYBACK STATE CALLBACK OVERRIDES --- override fun onSongUpdate(song: Song?) { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackSessionConnector.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackSessionConnector.kt index 10949356d..614c3a8be 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackSessionConnector.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackSessionConnector.kt @@ -6,21 +6,28 @@ import android.os.SystemClock import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.PlaybackStateCompat +import com.google.android.exoplayer2.Player import org.oxycblt.auxio.coil.loadBitmap import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.state.LoopMode import org.oxycblt.auxio.playback.state.PlaybackStateManager +/** + * Nightmarish class that coordinates communication between [MediaSessionCompat], [Player], + * and [PlaybackStateManager] + */ class PlaybackSessionConnector( private val context: Context, + private val player: Player, private val mediaSession: MediaSessionCompat -) : PlaybackStateManager.Callback, MediaSessionCompat.Callback() { +) : PlaybackStateManager.Callback, Player.Listener, MediaSessionCompat.Callback() { private val playbackManager = PlaybackStateManager.getInstance() private val emptyMetadata = MediaMetadataCompat.Builder().build() init { mediaSession.setCallback(this) playbackManager.addCallback(this) + player.addListener(this) onSongUpdate(playbackManager.song) onPlayingUpdate(playbackManager.isPlaying) @@ -28,6 +35,7 @@ class PlaybackSessionConnector( fun release() { playbackManager.removeCallback(this) + player.removeListener(this) } // --- MEDIASESSION CALLBACKS --- @@ -49,7 +57,7 @@ class PlaybackSessionConnector( } override fun onSeekTo(position: Long) { - playbackManager.seekTo(position) + player.seekTo(position) } override fun onRewind() { @@ -83,8 +91,6 @@ class PlaybackSessionConnector( // --- PLAYBACKSTATEMANAGER CALLBACKS --- override fun onSongUpdate(song: Song?) { - invalidateSessionState() - if (song == null) { mediaSession.setMetadata(emptyMetadata) return @@ -110,19 +116,32 @@ class PlaybackSessionConnector( invalidateSessionState() } - override fun onSeek(position: Long) { - invalidateSessionState() + // -- + + override fun onEvents(player: Player, events: Player.Events) { + if (events.containsAny( + Player.EVENT_POSITION_DISCONTINUITY, + Player.EVENT_PLAYBACK_STATE_CHANGED, + Player.EVENT_PLAY_WHEN_READY_CHANGED, + Player.EVENT_IS_PLAYING_CHANGED, + Player.EVENT_REPEAT_MODE_CHANGED, + Player.EVENT_PLAYBACK_PARAMETERS_CHANGED + ) + ) { + invalidateSessionState() + } } // --- MISC --- private fun invalidateSessionState() { - // Position updates arrive faster when you upload STATE_PAUSED for some inane reason. + // Position updates arrive faster when you upload STATE_PAUSED for some insane reason. val state = PlaybackStateCompat.Builder() .setActions(ACTIONS) + .setBufferedPosition(player.bufferedPosition) .setState( PlaybackStateCompat.STATE_PAUSED, - playbackManager.position, + player.currentPosition, 1.0f, SystemClock.elapsedRealtime() ) @@ -131,7 +150,7 @@ class PlaybackSessionConnector( state.setState( getPlayerState(), - playbackManager.position, + player.currentPosition, 1.0f, SystemClock.elapsedRealtime() )