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 63077e92d..bd208bc78 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 @@ -243,7 +243,7 @@ public final class VideoDetailFragment // It will do nothing if the player is not in fullscreen mode hideSystemUiIfNeeded(); - final Optional playerUi = player.UIs().get(MainPlayerUi.class); + final Optional playerUi = player.UIs().getOpt(MainPlayerUi.class); if (!player.videoPlayerSelected() && !playAfterConnect) { return; } @@ -519,7 +519,7 @@ public final class VideoDetailFragment binding.overlayPlayPauseButton.setOnClickListener(v -> { if (playerIsNotStopped()) { player.playPause(); - player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); + player.UIs().getOpt(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); showSystemUi(); } else { autoPlayEnabled = true; // forcefully start playing @@ -678,7 +678,7 @@ public final class VideoDetailFragment @Override public boolean onKeyDown(final int keyCode) { return isPlayerAvailable() - && player.UIs().get(VideoPlayerUi.class) + && player.UIs().getOpt(VideoPlayerUi.class) .map(playerUi -> playerUi.onKeyDown(keyCode)).orElse(false); } @@ -1018,7 +1018,7 @@ public final class VideoDetailFragment // If a user watched video inside fullscreen mode and than chose another player // return to non-fullscreen mode if (isPlayerAvailable()) { - player.UIs().get(MainPlayerUi.class).ifPresent(playerUi -> { + player.UIs().getOpt(MainPlayerUi.class).ifPresent(playerUi -> { if (playerUi.isFullscreen()) { playerUi.toggleFullscreen(); } @@ -1234,7 +1234,7 @@ public final class VideoDetailFragment // setup the surface view height, so that it fits the video correctly setHeightThumbnail(); - player.UIs().get(MainPlayerUi.class).ifPresent(playerUi -> { + player.UIs().getOpt(MainPlayerUi.class).ifPresent(playerUi -> { // sometimes binding would be null here, even though getView() != null above u.u if (binding != null) { // prevent from re-adding a view multiple times @@ -1250,7 +1250,7 @@ public final class VideoDetailFragment makeDefaultHeightForVideoPlaceholder(); if (player != null) { - player.UIs().get(VideoPlayerUi.class).ifPresent(VideoPlayerUi::removeViewFromParent); + player.UIs().getOpt(VideoPlayerUi.class).ifPresent(VideoPlayerUi::removeViewFromParent); } } @@ -1317,7 +1317,7 @@ public final class VideoDetailFragment binding.detailThumbnailImageView.setMinimumHeight(newHeight); if (isPlayerAvailable()) { final int maxHeight = (int) (metrics.heightPixels * MAX_PLAYER_HEIGHT); - player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> + player.UIs().getOpt(VideoPlayerUi.class).ifPresent(ui -> ui.getBinding().surfaceView.setHeights(newHeight, ui.isFullscreen() ? newHeight : maxHeight)); } @@ -1848,7 +1848,7 @@ public final class VideoDetailFragment public void onFullscreenStateChanged(final boolean fullscreen) { setupBrightness(); if (!isPlayerAndPlayerServiceAvailable() - || player.UIs().get(MainPlayerUi.class).isEmpty() + || player.UIs().getOpt(MainPlayerUi.class).isEmpty() || getRoot().map(View::getParent).isEmpty()) { return; } @@ -1877,7 +1877,7 @@ public final class VideoDetailFragment final boolean isLandscape = DeviceUtils.isLandscape(requireContext()); if (DeviceUtils.isTablet(activity) && (!globalScreenOrientationLocked(activity) || isLandscape)) { - player.UIs().get(MainPlayerUi.class).ifPresent(MainPlayerUi::toggleFullscreen); + player.UIs().getOpt(MainPlayerUi.class).ifPresent(MainPlayerUi::toggleFullscreen); return; } @@ -1977,7 +1977,7 @@ public final class VideoDetailFragment } private boolean isFullscreen() { - return isPlayerAvailable() && player.UIs().get(VideoPlayerUi.class) + return isPlayerAvailable() && player.UIs().getOpt(VideoPlayerUi.class) .map(VideoPlayerUi::isFullscreen).orElse(false); } @@ -2054,7 +2054,7 @@ public final class VideoDetailFragment setAutoPlay(true); } - player.UIs().get(MainPlayerUi.class).ifPresent(MainPlayerUi::checkLandscape); + player.UIs().getOpt(MainPlayerUi.class).ifPresent(MainPlayerUi::checkLandscape); // Let's give a user time to look at video information page if video is not playing if (globalScreenOrientationLocked(activity) && !player.isPlaying()) { player.play(); @@ -2319,7 +2319,7 @@ public final class VideoDetailFragment && player.isPlaying() && !isFullscreen() && !DeviceUtils.isTablet(activity)) { - player.UIs().get(MainPlayerUi.class) + player.UIs().getOpt(MainPlayerUi.class) .ifPresent(MainPlayerUi::toggleFullscreen); } setOverlayLook(binding.appBarLayout, behavior, 1); @@ -2333,7 +2333,7 @@ public final class VideoDetailFragment // Re-enable clicks setOverlayElementsClickable(true); if (isPlayerAvailable()) { - player.UIs().get(MainPlayerUi.class) + player.UIs().getOpt(MainPlayerUi.class) .ifPresent(MainPlayerUi::closeItemsList); } setOverlayLook(binding.appBarLayout, behavior, 0); @@ -2344,7 +2344,7 @@ public final class VideoDetailFragment showSystemUi(); } if (isPlayerAvailable()) { - player.UIs().get(MainPlayerUi.class).ifPresent(ui -> { + player.UIs().getOpt(MainPlayerUi.class).ifPresent(ui -> { if (ui.isControlsVisible()) { ui.hideControls(0, 0); } @@ -2441,7 +2441,7 @@ public final class VideoDetailFragment public Optional getRoot() { return Optional.ofNullable(player) - .flatMap(player1 -> player1.UIs().get(VideoPlayerUi.class)) + .flatMap(player1 -> player1.UIs().getOpt(VideoPlayerUi.class)) .map(playerUi -> playerUi.getBinding().getRoot()); } 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 ab5274996..5ec8e634c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -463,14 +463,15 @@ public final class Player implements PlaybackListener, Listener { } private void initUIsForCurrentPlayerType() { - if ((UIs.get(MainPlayerUi.class).isPresent() && playerType == PlayerType.MAIN) - || (UIs.get(PopupPlayerUi.class).isPresent() && playerType == PlayerType.POPUP)) { + if ((UIs.getOpt(MainPlayerUi.class).isPresent() && playerType == PlayerType.MAIN) + || (UIs.getOpt(PopupPlayerUi.class).isPresent() + && playerType == PlayerType.POPUP)) { // correct UI already in place return; } // try to reuse binding if possible - final PlayerBinding binding = UIs.get(VideoPlayerUi.class).map(VideoPlayerUi::getBinding) + final PlayerBinding binding = UIs.getOpt(VideoPlayerUi.class).map(VideoPlayerUi::getBinding) .orElseGet(() -> { if (playerType == PlayerType.AUDIO) { return null; 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 e7abf4320..393ccf75d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -66,7 +66,7 @@ public final class PlayerService extends Service { loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the service would never be put in the foreground while we said to the system we would do so */ - player.UIs().get(NotificationPlayerUi.class) + player.UIs().getOpt(NotificationPlayerUi.class) .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); } @@ -88,7 +88,7 @@ public final class PlayerService extends Service { do anything */ if (player != null) { - player.UIs().get(NotificationPlayerUi.class) + player.UIs().getOpt(NotificationPlayerUi.class) .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); } @@ -106,7 +106,7 @@ public final class PlayerService extends Service { if (player != null) { player.handleIntent(intent); - player.UIs().get(MediaSessionPlayerUi.class) + player.UIs().getOpt(MediaSessionPlayerUi.class) .ifPresent(ui -> ui.handleMediaButtonIntent(intent)); } 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 c673e688c..c3b427e23 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 @@ -145,7 +145,7 @@ public class MediaSessionPlayerUi extends PlayerUi public void play() { player.play(); // hide the player controls even if the play command came from the media session - player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); + player.UIs().getOpt(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java index 30420b0c7..5658693f2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java @@ -102,7 +102,7 @@ public final class NotificationUtil { mediaStyle.setShowActionsInCompactView(compactSlots); } player.UIs() - .get(MediaSessionPlayerUi.class) + .getOpt(MediaSessionPlayerUi.class) .flatMap(MediaSessionPlayerUi::getSessionToken) .ifPresent(mediaStyle::setMediaSession); diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/PlayerUiList.kt b/app/src/main/java/org/schabi/newpipe/player/ui/PlayerUiList.kt index 46090285f..460dfeb0e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/PlayerUiList.kt +++ b/app/src/main/java/org/schabi/newpipe/player/ui/PlayerUiList.kt @@ -65,21 +65,32 @@ class PlayerUiList(vararg initialPlayerUis: PlayerUi) { * @param playerUiType the class of the player UI to return; * the [Class.isInstance] method will be used, so even subclasses could be returned * @param T the class type parameter - * @return the first player UI of the required type found in the list, or an empty - * [ ] otherwise + * @return the first player UI of the required type found in the list, or null */ - fun get(playerUiType: Class): Optional { + fun get(playerUiType: Class): T? { for (ui in playerUis) { if (playerUiType.isInstance(ui)) { when (val r = playerUiType.cast(ui)) { + // try all UIs before returning null null -> continue - else -> return Optional.of(r) + else -> return r } } } - return Optional.empty() + return null } + /** + * @param playerUiType the class of the player UI to return; + * the [Class.isInstance] method will be used, so even subclasses could be returned + * @param T the class type parameter + * @return the first player UI of the required type found in the list, or an empty + * [ ] otherwise + */ + @Deprecated("use get", ReplaceWith("get(playerUiType)")) + fun getOpt(playerUiType: Class): Optional = + Optional.ofNullable(get(playerUiType)) + /** * Calls the provided consumer on all player UIs in the list, in order of addition. * @param consumer the consumer to call with player UIs