From 53bf9b68fefa3275560513068e95c70c97578a53 Mon Sep 17 00:00:00 2001 From: Haggai Eran Date: Mon, 2 Jan 2023 21:43:28 +0200 Subject: [PATCH] Keep MediaSessionCompat and MediaSessionConnector in a separate class These objects need to live beyond the player for supporting MediaBrowserServiceCompat and Android Auto, so they need to move outside of the MediaSessionPlayerUi class. --- .../org/schabi/newpipe/player/Player.java | 2 +- .../schabi/newpipe/player/PlayerService.java | 22 ++++++++++- .../mediabrowser/MediaBrowserConnector.java | 32 ++++++++++++++++ .../mediasession/MediaSessionPlayerUi.java | 38 ++++++++----------- 4 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserConnector.java diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 1a8283590bc..2db8e9529d9 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -301,7 +301,7 @@ public Player(@NonNull final PlayerService service) { // notification ui in the UIs list, since the notification depends on the media session in // PlayerUi#initPlayer(), and UIs.call() guarantees UI order is preserved. UIs = new PlayerUiList( - new MediaSessionPlayerUi(this), + new MediaSessionPlayerUi(this, service.getSessionConnector()), new NotificationPlayerUi(this) ); } diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index ad6c9405dd0..b9650a26c5e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -28,6 +28,9 @@ import android.os.IBinder; import android.util.Log; +import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; + +import org.schabi.newpipe.player.mediabrowser.MediaBrowserConnector; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.util.ThemeHelper; @@ -46,6 +49,9 @@ public final class PlayerService extends Service { private final IBinder mBinder = new PlayerService.LocalBinder(this); + private MediaBrowserConnector mediaBrowserConnector; + + /*////////////////////////////////////////////////////////////////////////// // Service's LifeCycle //////////////////////////////////////////////////////////////////////////*/ @@ -58,7 +64,13 @@ public void onCreate() { assureCorrectAppLanguage(this); ThemeHelper.setTheme(this); - player = new Player(this); + mediaBrowserConnector = new MediaBrowserConnector(this); + } + + private void initializePlayer() { + if (player == null) { + player = new Player(this); + } } @Override @@ -75,6 +87,7 @@ public int onStartCommand(final Intent intent, final int flags, final int startI return START_NOT_STICKY; } + initializePlayer(); player.handleIntent(intent); player.UIs().get(MediaSessionPlayerUi.class) .ifPresent(ui -> ui.handleMediaButtonIntent(intent)); @@ -112,6 +125,10 @@ public void onDestroy() { Log.d(TAG, "destroy() called"); } cleanup(); + if (mediaBrowserConnector != null) { + mediaBrowserConnector.release(); + mediaBrowserConnector = null; + } } private void cleanup() { @@ -136,6 +153,9 @@ public IBinder onBind(final Intent intent) { return mBinder; } + public MediaSessionConnector getSessionConnector() { + return mediaBrowserConnector.getSessionConnector(); + } public static class LocalBinder extends Binder { private final WeakReference playerService; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserConnector.java b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserConnector.java new file mode 100644 index 00000000000..6fc61c3d748 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserConnector.java @@ -0,0 +1,32 @@ +package org.schabi.newpipe.player.mediabrowser; + +import android.support.v4.media.session.MediaSessionCompat; + +import androidx.annotation.NonNull; + +import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; + +import org.schabi.newpipe.player.PlayerService; + +public class MediaBrowserConnector { + private static final String TAG = MediaBrowserConnector.class.getSimpleName(); + + private final PlayerService playerService; + private final @NonNull MediaSessionConnector sessionConnector; + private final @NonNull MediaSessionCompat mediaSession; + + public MediaBrowserConnector(@NonNull final PlayerService playerService) { + this.playerService = playerService; + mediaSession = new MediaSessionCompat(playerService, TAG); + sessionConnector = new MediaSessionConnector(mediaSession); + sessionConnector.setMetadataDeduplicationEnabled(true); + } + + public @NonNull MediaSessionConnector getSessionConnector() { + return sessionConnector; + } + + public void release() { + mediaSession.release(); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java index 6f76a91d1c0..caeb90dadac 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java @@ -28,14 +28,17 @@ public class MediaSessionPlayerUi extends PlayerUi implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "MediaSessUi"; - private MediaSessionCompat mediaSession; - private MediaSessionConnector sessionConnector; + private final @NonNull MediaSessionCompat mediaSession; + private final @NonNull MediaSessionConnector sessionConnector; private final String ignoreHardwareMediaButtonsKey; private boolean shouldIgnoreHardwareMediaButtons = false; - public MediaSessionPlayerUi(@NonNull final Player player) { + public MediaSessionPlayerUi(@NonNull final Player player, + @NonNull final MediaSessionConnector sessionConnector) { super(player); + this.mediaSession = sessionConnector.mediaSession; + this.sessionConnector = sessionConnector; ignoreHardwareMediaButtonsKey = context.getString(R.string.ignore_hardware_media_buttons_key); } @@ -45,10 +48,8 @@ public void initPlayer() { super.initPlayer(); destroyPlayer(); // release previously used resources - mediaSession = new MediaSessionCompat(context, TAG); mediaSession.setActive(true); - sessionConnector = new MediaSessionConnector(mediaSession); sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, player)); sessionConnector.setPlayer(getForwardingPlayer()); @@ -61,7 +62,6 @@ public void initPlayer() { updateShouldIgnoreHardwareMediaButtons(player.getPrefs()); player.getPrefs().registerOnSharedPreferenceChangeListener(this); - sessionConnector.setMetadataDeduplicationEnabled(true); sessionConnector.setMediaMetadataProvider(exoPlayer -> buildMediaMetadata()); } @@ -69,26 +69,20 @@ public void initPlayer() { public void destroyPlayer() { super.destroyPlayer(); player.getPrefs().unregisterOnSharedPreferenceChangeListener(this); - if (sessionConnector != null) { - sessionConnector.setMediaButtonEventHandler(null); - sessionConnector.setPlayer(null); - sessionConnector.setQueueNavigator(null); - sessionConnector = null; - } - if (mediaSession != null) { - mediaSession.setActive(false); - mediaSession.release(); - mediaSession = null; - } + sessionConnector.setMediaButtonEventHandler(null); + sessionConnector.setPlayer(null); + sessionConnector.setQueueNavigator(null); + sessionConnector.setMediaMetadataProvider(null); + + mediaSession.setActive(false); } @Override public void onThumbnailLoaded(@Nullable final Bitmap bitmap) { super.onThumbnailLoaded(bitmap); - if (sessionConnector != null) { - // the thumbnail is now loaded: invalidate the metadata to trigger a metadata update - sessionConnector.invalidateMediaSessionMetadata(); - } + + // the thumbnail is now loaded: invalidate the metadata to trigger a metadata update + sessionConnector.invalidateMediaSessionMetadata(); } @@ -111,7 +105,7 @@ public void handleMediaButtonIntent(final Intent intent) { } public Optional getSessionToken() { - return Optional.ofNullable(mediaSession).map(MediaSessionCompat::getSessionToken); + return Optional.of(mediaSession.getSessionToken()); }