Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 15 additions & 21 deletions app/src/main/java/org/schabi/newpipe/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
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;

Expand Down Expand Up @@ -127,6 +128,7 @@
import org.schabi.newpipe.util.image.PicassoHelper;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.IntStream;

Expand Down Expand Up @@ -351,25 +353,17 @@ public int getOverrideResolutionIndex(final List<VideoStream> sortedVideos,

@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();

Expand Down Expand Up @@ -410,15 +404,15 @@ public void handleIntent(@NonNull final Intent intent) {
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<StreamInfo> 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,
Expand All @@ -432,7 +426,7 @@ public void handleIntent(@NonNull final Intent intent) {
simpleExoPlayer.prepare();
}
simpleExoPlayer.seekTo(oldPlayQueue.getIndex(),
dat.getSeconds() * 1000L);
data.getSeconds() * 1000L);
simpleExoPlayer.setPlayWhenReady(playWhenReady);

} else {
Expand All @@ -456,9 +450,9 @@ public void handleIntent(@NonNull final Intent intent) {
// 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
25 changes: 0 additions & 25 deletions app/src/main/java/org/schabi/newpipe/player/PlayerType.java
Original file line number Diff line number Diff line change
@@ -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())];
}
}
57 changes: 23 additions & 34 deletions app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Parcelable;
import android.util.Log;
import android.widget.Toast;

Expand Down Expand Up @@ -70,6 +69,7 @@
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";
Expand All @@ -89,31 +89,22 @@ public static <T> Intent getPlayerIntent(@NonNull final Context context,
@NonNull final Class<T> 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
Expand Down Expand Up @@ -156,9 +147,9 @@ public static void playOnPopupPlayer(final Context context,

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);
}
Expand All @@ -170,9 +161,9 @@ public static void playOnBackgroundPlayer(final Context context,
.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);
}

Expand All @@ -195,9 +186,8 @@ public static void enqueueOnPlayer(final Context context,
// 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);
}

Expand All @@ -219,9 +209,8 @@ public static void enqueueNextOnPlayer(final Context context, final PlayQueue qu
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);
}

Expand Down