diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index eb497cd79..976d5bdbe 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -95,7 +95,8 @@ import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.PlayerService; import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.event.OnKeyDownListener; -import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener; +import org.schabi.newpipe.player.event.PlayerHolderLifecycleEventListener; +import org.schabi.newpipe.player.event.PlayerServiceEventListener; import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.player.helper.PlayerHolder; import org.schabi.newpipe.player.playqueue.PlayQueue; @@ -136,7 +137,8 @@ import io.reactivex.rxjava3.schedulers.Schedulers; public final class VideoDetailFragment extends BaseStateFragment implements BackPressable, - PlayerServiceExtendedEventListener, + PlayerServiceEventListener, + PlayerHolderLifecycleEventListener, OnKeyDownListener { public static final String KEY_SWITCHING_PLAYERS = "switching_players"; @@ -392,7 +394,7 @@ public final class VideoDetailFragment if (activity.isFinishing() && isPlayerAvailable() && player.videoPlayerSelected()) { playerHolder.stopService(); } else { - playerHolder.setListener(null); + playerHolder.unsetListeners(); } PreferenceManager.getDefaultSharedPreferences(activity) @@ -660,7 +662,7 @@ public final class VideoDetailFragment if (playerHolder.isNotBoundYet()) { setHeightThumbnail(); } else { - playerHolder.startService(false, this); + playerHolder.startService(false, this, this); } } @@ -1051,7 +1053,7 @@ public final class VideoDetailFragment // See UI changes while remote playQueue changes if (!isPlayerAvailable()) { - playerHolder.startService(false, this); + playerHolder.startService(false, this, this); } else { // FIXME Workaround #7427 player.setRecovery(); @@ -1114,7 +1116,7 @@ public final class VideoDetailFragment private void openNormalBackgroundPlayer(final boolean append) { // See UI changes while remote playQueue changes if (!isPlayerAvailable()) { - playerHolder.startService(false, this); + playerHolder.startService(false, this, this); } final PlayQueue queue = setupPlayQueueForIntent(append); @@ -1128,7 +1130,7 @@ public final class VideoDetailFragment private void openMainPlayer() { if (!isPlayerServiceAvailable()) { - playerHolder.startService(autoPlayEnabled, this); + playerHolder.startService(autoPlayEnabled, this, this); return; } if (currentInfo == null) { @@ -1385,7 +1387,9 @@ public final class VideoDetailFragment // Rebound to the service if it was closed via notification or mini player if (playerHolder.isNotBoundYet()) { playerHolder.startService( - false, VideoDetailFragment.this); + false, + VideoDetailFragment.this, + VideoDetailFragment.this); } break; } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerEventListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerEventListener.java index 2cca259c2..80c795e8c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerEventListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerEventListener.java @@ -5,6 +5,7 @@ import com.google.android.exoplayer2.PlaybackParameters; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.player.playqueue.PlayQueue; +/** Player-specific events like queue or progress updates. */ public interface PlayerEventListener { void onQueueUpdate(PlayQueue queue); void onPlaybackUpdate(int state, int repeatMode, boolean shuffled, diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerHolderLifecycleEventListener.java similarity index 64% rename from app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java rename to app/src/main/java/org/schabi/newpipe/player/event/PlayerHolderLifecycleEventListener.java index 9e8c7cf76..e5eaa09c7 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerHolderLifecycleEventListener.java @@ -2,7 +2,8 @@ package org.schabi.newpipe.player.event; import org.schabi.newpipe.player.PlayerService; -public interface PlayerServiceExtendedEventListener extends PlayerServiceEventListener { +/** Gets signalled if our PlayerHolder (dis)connects from the PlayerService. */ +public interface PlayerHolderLifecycleEventListener { void onServiceConnected(PlayerService playerService, boolean playAfterConnect); void onServiceDisconnected(); diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java index 8c18fd2ad..5feaebc00 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java @@ -2,6 +2,9 @@ package org.schabi.newpipe.player.event; import com.google.android.exoplayer2.PlaybackException; +/** {@link org.schabi.newpipe.player.event.PlayerEventListener} that also gets called for + * application-specific events like screen rotation or UI changes. + */ public interface PlayerServiceEventListener extends PlayerEventListener { void onViewCreated(); diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index 92ef16d0c..478436d93 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -7,6 +7,7 @@ import android.content.ServiceConnection; import android.os.IBinder; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; @@ -20,7 +21,7 @@ import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.PlayerService; import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.event.PlayerServiceEventListener; -import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener; +import org.schabi.newpipe.player.event.PlayerHolderLifecycleEventListener; import org.schabi.newpipe.player.playqueue.PlayQueue; /** Singleton that manages a `PlayerService` @@ -41,7 +42,8 @@ public final class PlayerHolder { private static final boolean DEBUG = MainActivity.DEBUG; private static final String TAG = PlayerHolder.class.getSimpleName(); - @Nullable private PlayerServiceExtendedEventListener listener; + @Nullable private PlayerServiceEventListener listener; + @Nullable private PlayerHolderLifecycleEventListener holderListener; private final PlayerServiceConnection serviceConnection = new PlayerServiceConnection(); private boolean bound; @@ -102,16 +104,19 @@ public final class PlayerHolder { return player.getPlayQueue().getIndex(); } - public void setListener(@Nullable final PlayerServiceExtendedEventListener newListener) { - listener = newListener; + public void unsetListeners() { + listener = null; + holderListener = null; + } - if (listener == null) { - return; - } + public void setListener(@NonNull final PlayerServiceEventListener newListener, + @NonNull final PlayerHolderLifecycleEventListener newHolderListener) { + listener = newListener; + holderListener = newHolderListener; // Force reload data from service if (player != null) { - listener.onServiceConnected(playerService, false); + holderListener.onServiceConnected(playerService, false); player.setFragmentListener(internalListener); } } @@ -131,11 +136,14 @@ public final class PlayerHolder { * If the service is already started, only set the listener. * @param playAfterConnect If the service is started, start playing immediately * @param newListener set this listener + * @param newHolderListener set this listener * */ public void startService(final boolean playAfterConnect, - final PlayerServiceExtendedEventListener newListener) { + final PlayerServiceEventListener newListener, + final PlayerHolderLifecycleEventListener newHolderListener + ) { final Context context = getCommonContext(); - setListener(newListener); + setListener(newListener, newHolderListener); if (bound) { return; } @@ -182,8 +190,8 @@ public final class PlayerHolder { } playerService = null; player = null; - if (listener != null) { - listener.onServiceDisconnected(); + if (holderListener != null) { + holderListener.onServiceDisconnected(); } } } @@ -212,8 +220,8 @@ public final class PlayerHolder { playerService = localBinder.getService(); player = playerService != null ? playerService.getPlayer() : null; - if (listener != null) { - listener.onServiceConnected(playerService, playAfterConnect); + if (holderListener != null) { + holderListener.onServiceConnected(playerService, playAfterConnect); } if (player != null) { player.setFragmentListener(internalListener);