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 6c12a74d4..39f941693 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -61,6 +61,7 @@ import android.view.LayoutInflater; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; +import androidx.core.content.IntentCompat; import androidx.core.math.MathUtils; import androidx.preference.PreferenceManager; @@ -127,6 +128,7 @@ import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.IntStream; @@ -351,25 +353,17 @@ public final class Player implements PlaybackListener, Listener { @SuppressWarnings("MethodLength") public void handleIntent(@NonNull final Intent intent) { - - final PlayerIntentType playerIntentType = intent.getParcelableExtra(PLAYER_INTENT_TYPE); + final var playerIntentType = IntentCompat.getSerializableExtra(intent, PLAYER_INTENT_TYPE, + PlayerIntentType.class); if (playerIntentType == null) { return; } - final PlayerType newPlayerType; // TODO: this should be in the second switch below, but I’m not sure whether I // can move the initUIs stuff without breaking the setup for edge cases somehow. - switch (playerIntentType) { - case TimestampChange -> { - // when playing from a timestamp, keep the current player as-is. - newPlayerType = playerType; - } - default -> { - newPlayerType = PlayerType.retrieveFromIntent(intent); - } + // when playing from a timestamp, keep the current player as-is. + if (playerIntentType != PlayerIntentType.TimestampChange) { + playerType = IntentCompat.getSerializableExtra(intent, PLAYER_TYPE, PlayerType.class); } - - playerType = newPlayerType; initUIsForCurrentPlayerType(); isAudioOnly = audioPlayerSelected(); @@ -410,15 +404,15 @@ public final class Player implements PlaybackListener, Listener { break; } case TimestampChange -> { - final TimestampChangeData dat = intent.getParcelableExtra(PLAYER_INTENT_DATA); - assert dat != null; + final var data = Objects.requireNonNull(IntentCompat.getParcelableExtra(intent, + PLAYER_INTENT_DATA, TimestampChangeData.class)); final Single single = - ExtractorHelper.getStreamInfo(dat.getServiceId(), dat.getUrl(), false); + ExtractorHelper.getStreamInfo(data.getServiceId(), data.getUrl(), false); streamItemDisposable.add(single.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(info -> { final @Nullable PlayQueue oldPlayQueue = playQueue; - info.setStartPosition(dat.getSeconds()); + info.setStartPosition(data.getSeconds()); final PlayQueueItem playQueueItem = new PlayQueueItem(info); // If the stream is already playing, @@ -432,7 +426,7 @@ public final class Player implements PlaybackListener, Listener { simpleExoPlayer.prepare(); } simpleExoPlayer.seekTo(oldPlayQueue.getIndex(), - dat.getSeconds() * 1000L); + data.getSeconds() * 1000L); simpleExoPlayer.setPlayWhenReady(playWhenReady); } else { @@ -456,9 +450,9 @@ public final class Player implements PlaybackListener, Listener { // This will only show a snackbar if the passed context has a root view: // otherwise it will resort to showing a notification, so we are safe // here. - ErrorUtil.createNotification(context, - new ErrorInfo(throwable, UserAction.PLAY_ON_POPUP, dat.getUrl(), - null, dat.getUrl())); + final var info = new ErrorInfo(throwable, UserAction.PLAY_ON_POPUP, + data.getUrl(), null, data.getUrl()); + ErrorUtil.createNotification(context, info); })); return; } diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerIntentType.kt b/app/src/main/java/org/schabi/newpipe/player/PlayerIntentType.kt index d9d83c69c..ed0c19c99 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerIntentType.kt +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerIntentType.kt @@ -6,9 +6,7 @@ import kotlinx.parcelize.Parcelize // We model this as an enum class plus one struct for each enum value // so we can consume it from Java properly. After converting to Kotlin, // we could switch to a sealed enum class & a proper Kotlin `when` match. - -@Parcelize -enum class PlayerIntentType : Parcelable { +enum class PlayerIntentType { Enqueue, EnqueueNext, TimestampChange, diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerType.java b/app/src/main/java/org/schabi/newpipe/player/PlayerType.java index 171a70395..f74389d79 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerType.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerType.java @@ -1,32 +1,7 @@ package org.schabi.newpipe.player; -import static org.schabi.newpipe.player.Player.PLAYER_TYPE; - -import android.content.Intent; - public enum PlayerType { MAIN, AUDIO, POPUP; - - /** - * @return an integer representing this {@link PlayerType}, to be used to save it in intents - * @see #retrieveFromIntent(Intent) Use retrieveFromIntent() to retrieve and convert player type - * integers from an intent - */ - public int valueForIntent() { - return ordinal(); - } - - /** - * @param intent the intent to retrieve a player type from - * @return the player type integer retrieved from the intent, converted back into a {@link - * PlayerType}, or {@link PlayerType#MAIN} if there is no player type extra in the - * intent - * @throws ArrayIndexOutOfBoundsException if the intent contains an invalid player type integer - * @see #valueForIntent() Use valueForIntent() to obtain valid player type integers - */ - public static PlayerType retrieveFromIntent(final Intent intent) { - return values()[intent.getIntExtra(PLAYER_TYPE, MAIN.valueForIntent())]; - } } diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java index bc2f21c27..f702c5bd5 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -9,7 +9,6 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; -import android.os.Parcelable; import android.util.Log; import android.widget.Toast; @@ -70,6 +69,7 @@ import org.schabi.newpipe.settings.SettingsActivity; import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.List; +import java.util.Optional; public final class NavigationHelper { public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag"; @@ -89,31 +89,22 @@ public final class NavigationHelper { @NonNull final Class targetClazz, @Nullable final PlayQueue playQueue, @NonNull final PlayerIntentType playerIntentType) { - final Intent intent = new Intent(context, targetClazz); - - if (playQueue != null) { - final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class); - if (cacheKey != null) { - intent.putExtra(Player.PLAY_QUEUE_KEY, cacheKey); - } - } - intent.putExtra(Player.PLAYER_TYPE, PlayerType.MAIN.valueForIntent()); - intent.putExtra(PlayerService.SHOULD_START_FOREGROUND_EXTRA, true); - intent.putExtra(Player.PLAYER_INTENT_TYPE, (Parcelable) playerIntentType); - - return intent; + final String cacheKey = Optional.ofNullable(playQueue) + .map(queue -> SerializedCache.getInstance().put(queue, PlayQueue.class)) + .orElse(null); + return new Intent(context, targetClazz) + .putExtra(Player.PLAY_QUEUE_KEY, cacheKey) + .putExtra(Player.PLAYER_TYPE, PlayerType.MAIN) + .putExtra(PlayerService.SHOULD_START_FOREGROUND_EXTRA, true) + .putExtra(Player.PLAYER_INTENT_TYPE, playerIntentType); } @NonNull public static Intent getPlayerTimestampIntent(@NonNull final Context context, - @NonNull final TimestampChangeData - timestampChangeData) { - final Intent intent = new Intent(context, PlayerService.class); - - intent.putExtra(Player.PLAYER_INTENT_TYPE, (Parcelable) PlayerIntentType.TimestampChange); - intent.putExtra(Player.PLAYER_INTENT_DATA, timestampChangeData); - - return intent; + @NonNull final TimestampChangeData data) { + return new Intent(context, PlayerService.class) + .putExtra(Player.PLAYER_INTENT_TYPE, PlayerIntentType.TimestampChange) + .putExtra(Player.PLAYER_INTENT_DATA, data); } @NonNull @@ -156,9 +147,9 @@ public final class NavigationHelper { Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show(); - final Intent intent = getPlayerIntent(context, PlayerService.class, queue, - PlayerIntentType.AllOthers); - intent.putExtra(Player.PLAYER_TYPE, PlayerType.POPUP.valueForIntent()) + final var intent = getPlayerIntent(context, PlayerService.class, queue, + PlayerIntentType.AllOthers) + .putExtra(Player.PLAYER_TYPE, PlayerType.POPUP) .putExtra(Player.RESUME_PLAYBACK, resumePlayback); ContextCompat.startForegroundService(context, intent); } @@ -170,9 +161,9 @@ public final class NavigationHelper { .show(); final Intent intent = getPlayerIntent(context, PlayerService.class, queue, - PlayerIntentType.AllOthers); - intent.putExtra(Player.PLAYER_TYPE, PlayerType.AUDIO.valueForIntent()); - intent.putExtra(Player.RESUME_PLAYBACK, resumePlayback); + PlayerIntentType.AllOthers) + .putExtra(Player.PLAYER_TYPE, PlayerType.AUDIO) + .putExtra(Player.RESUME_PLAYBACK, resumePlayback); ContextCompat.startForegroundService(context, intent); } @@ -195,9 +186,8 @@ public final class NavigationHelper { // by long pressing the video detail fragment, playlist or channel controls final Intent intent = getPlayerIntent(context, PlayerService.class, queue, PlayerIntentType.Enqueue) - .putExtra(Player.RESUME_PLAYBACK, false); - - intent.putExtra(Player.PLAYER_TYPE, playerType.valueForIntent()); + .putExtra(Player.RESUME_PLAYBACK, false) + .putExtra(Player.PLAYER_TYPE, playerType); ContextCompat.startForegroundService(context, intent); } @@ -219,9 +209,8 @@ public final class NavigationHelper { playerType = PlayerType.AUDIO; } Toast.makeText(context, R.string.enqueued_next, Toast.LENGTH_SHORT).show(); - final Intent intent = getPlayerEnqueueNextIntent(context, PlayerService.class, queue); - - intent.putExtra(Player.PLAYER_TYPE, playerType.valueForIntent()); + final Intent intent = getPlayerEnqueueNextIntent(context, PlayerService.class, queue) + .putExtra(Player.PLAYER_TYPE, playerType); ContextCompat.startForegroundService(context, intent); }