Move all notification-related calls to NotificationPlayerUi

This commit is contained in:
Stypox 2022-04-14 18:14:28 +02:00
parent b3f99645a3
commit 0bba1d95de
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
4 changed files with 155 additions and 111 deletions

View File

@ -45,22 +45,16 @@ public final class NotificationUtil {
private static final boolean DEBUG = Player.DEBUG; private static final boolean DEBUG = Player.DEBUG;
private static final int NOTIFICATION_ID = 123789; private static final int NOTIFICATION_ID = 123789;
@Nullable private static NotificationUtil instance = null;
@NotificationConstants.Action @NotificationConstants.Action
private final int[] notificationSlots = NotificationConstants.SLOT_DEFAULTS.clone(); private final int[] notificationSlots = NotificationConstants.SLOT_DEFAULTS.clone();
private NotificationManagerCompat notificationManager; private NotificationManagerCompat notificationManager;
private NotificationCompat.Builder notificationBuilder; private NotificationCompat.Builder notificationBuilder;
private NotificationUtil() { private Player player;
}
public static NotificationUtil getInstance() { public NotificationUtil(final Player player) {
if (instance == null) { this.player = player;
instance = new NotificationUtil();
}
return instance;
} }
@ -71,20 +65,18 @@ public final class NotificationUtil {
/** /**
* Creates the notification if it does not exist already and recreates it if forceRecreate is * Creates the notification if it does not exist already and recreates it if forceRecreate is
* true. Updates the notification with the data in the player. * true. Updates the notification with the data in the player.
* @param player the player currently open, to take data from
* @param forceRecreate whether to force the recreation of the notification even if it already * @param forceRecreate whether to force the recreation of the notification even if it already
* exists * exists
*/ */
synchronized void createNotificationIfNeededAndUpdate(final Player player, public synchronized void createNotificationIfNeededAndUpdate(final boolean forceRecreate) {
final boolean forceRecreate) {
if (forceRecreate || notificationBuilder == null) { if (forceRecreate || notificationBuilder == null) {
notificationBuilder = createNotification(player); notificationBuilder = createNotification();
} }
updateNotification(player); updateNotification();
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
} }
private synchronized NotificationCompat.Builder createNotification(final Player player) { private synchronized NotificationCompat.Builder createNotification() {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "createNotification()"); Log.d(TAG, "createNotification()");
} }
@ -93,7 +85,7 @@ public final class NotificationUtil {
new NotificationCompat.Builder(player.getContext(), new NotificationCompat.Builder(player.getContext(),
player.getContext().getString(R.string.notification_channel_id)); player.getContext().getString(R.string.notification_channel_id));
initializeNotificationSlots(player); initializeNotificationSlots();
// count the number of real slots, to make sure compact slots indices are not out of bound // count the number of real slots, to make sure compact slots indices are not out of bound
int nonNothingSlotCount = 5; int nonNothingSlotCount = 5;
@ -132,9 +124,8 @@ public final class NotificationUtil {
/** /**
* Updates the notification builder and the button icons depending on the playback state. * Updates the notification builder and the button icons depending on the playback state.
* @param player the player currently open, to take data from
*/ */
private synchronized void updateNotification(final Player player) { private synchronized void updateNotification() {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "updateNotification()"); Log.d(TAG, "updateNotification()");
} }
@ -145,17 +136,17 @@ public final class NotificationUtil {
notificationBuilder.setContentTitle(player.getVideoTitle()); notificationBuilder.setContentTitle(player.getVideoTitle());
notificationBuilder.setContentText(player.getUploaderName()); notificationBuilder.setContentText(player.getUploaderName());
notificationBuilder.setTicker(player.getVideoTitle()); notificationBuilder.setTicker(player.getVideoTitle());
updateActions(notificationBuilder, player); updateActions(notificationBuilder);
final boolean showThumbnail = player.getPrefs().getBoolean( final boolean showThumbnail = player.getPrefs().getBoolean(
player.getContext().getString(R.string.show_thumbnail_key), true); player.getContext().getString(R.string.show_thumbnail_key), true);
if (showThumbnail) { if (showThumbnail) {
setLargeIcon(notificationBuilder, player); setLargeIcon(notificationBuilder);
} }
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
boolean shouldUpdateBufferingSlot() { public boolean shouldUpdateBufferingSlot() {
if (notificationBuilder == null) { if (notificationBuilder == null) {
// if there is no notification active, there is no point in updating it // if there is no notification active, there is no point in updating it
return false; return false;
@ -173,22 +164,22 @@ public final class NotificationUtil {
} }
public void createNotificationAndStartForeground(final Player player, final Service service) { public void createNotificationAndStartForeground() {
if (notificationBuilder == null) { if (notificationBuilder == null) {
notificationBuilder = createNotification(player); notificationBuilder = createNotification();
} }
updateNotification(player); updateNotification();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
service.startForeground(NOTIFICATION_ID, notificationBuilder.build(), player.getService().startForeground(NOTIFICATION_ID, notificationBuilder.build(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK); ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
} else { } else {
service.startForeground(NOTIFICATION_ID, notificationBuilder.build()); player.getService().startForeground(NOTIFICATION_ID, notificationBuilder.build());
} }
} }
void cancelNotificationAndStopForeground(final Service service) { public void cancelNotificationAndStopForeground() {
ServiceCompat.stopForeground(service, ServiceCompat.STOP_FOREGROUND_REMOVE); ServiceCompat.stopForeground(player.getService(), ServiceCompat.STOP_FOREGROUND_REMOVE);
if (notificationManager != null) { if (notificationManager != null) {
notificationManager.cancel(NOTIFICATION_ID); notificationManager.cancel(NOTIFICATION_ID);
@ -202,7 +193,7 @@ public final class NotificationUtil {
// ACTIONS // ACTIONS
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
private void initializeNotificationSlots(final Player player) { private void initializeNotificationSlots() {
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
notificationSlots[i] = player.getPrefs().getInt( notificationSlots[i] = player.getPrefs().getInt(
player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]), player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
@ -211,7 +202,7 @@ public final class NotificationUtil {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
private void updateActions(final NotificationCompat.Builder builder, final Player player) { private void updateActions(final NotificationCompat.Builder builder) {
builder.mActions.clear(); builder.mActions.clear();
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
addAction(builder, player, notificationSlots[i]); addAction(builder, player, notificationSlots[i]);
@ -221,7 +212,7 @@ public final class NotificationUtil {
private void addAction(final NotificationCompat.Builder builder, private void addAction(final NotificationCompat.Builder builder,
final Player player, final Player player,
@NotificationConstants.Action final int slot) { @NotificationConstants.Action final int slot) {
final NotificationCompat.Action action = getAction(player, slot); final NotificationCompat.Action action = getAction(slot);
if (action != null) { if (action != null) {
builder.addAction(action); builder.addAction(action);
} }
@ -229,41 +220,40 @@ public final class NotificationUtil {
@Nullable @Nullable
private NotificationCompat.Action getAction( private NotificationCompat.Action getAction(
final Player player,
@NotificationConstants.Action final int selectedAction) { @NotificationConstants.Action final int selectedAction) {
final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction]; final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction];
switch (selectedAction) { switch (selectedAction) {
case NotificationConstants.PREVIOUS: case NotificationConstants.PREVIOUS:
return getAction(player, baseActionIcon, return getAction(baseActionIcon,
R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS); R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS);
case NotificationConstants.NEXT: case NotificationConstants.NEXT:
return getAction(player, baseActionIcon, return getAction(baseActionIcon,
R.string.exo_controls_next_description, ACTION_PLAY_NEXT); R.string.exo_controls_next_description, ACTION_PLAY_NEXT);
case NotificationConstants.REWIND: case NotificationConstants.REWIND:
return getAction(player, baseActionIcon, return getAction(baseActionIcon,
R.string.exo_controls_rewind_description, ACTION_FAST_REWIND); R.string.exo_controls_rewind_description, ACTION_FAST_REWIND);
case NotificationConstants.FORWARD: case NotificationConstants.FORWARD:
return getAction(player, baseActionIcon, return getAction(baseActionIcon,
R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD); R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD);
case NotificationConstants.SMART_REWIND_PREVIOUS: case NotificationConstants.SMART_REWIND_PREVIOUS:
if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) { if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
return getAction(player, R.drawable.exo_notification_previous, return getAction(R.drawable.exo_notification_previous,
R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS); R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS);
} else { } else {
return getAction(player, R.drawable.exo_controls_rewind, return getAction(R.drawable.exo_controls_rewind,
R.string.exo_controls_rewind_description, ACTION_FAST_REWIND); R.string.exo_controls_rewind_description, ACTION_FAST_REWIND);
} }
case NotificationConstants.SMART_FORWARD_NEXT: case NotificationConstants.SMART_FORWARD_NEXT:
if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) { if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
return getAction(player, R.drawable.exo_notification_next, return getAction(R.drawable.exo_notification_next,
R.string.exo_controls_next_description, ACTION_PLAY_NEXT); R.string.exo_controls_next_description, ACTION_PLAY_NEXT);
} else { } else {
return getAction(player, R.drawable.exo_controls_fastforward, return getAction(R.drawable.exo_controls_fastforward,
R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD); R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD);
} }
@ -279,42 +269,42 @@ public final class NotificationUtil {
case NotificationConstants.PLAY_PAUSE: case NotificationConstants.PLAY_PAUSE:
if (player.getCurrentState() == Player.STATE_COMPLETED) { if (player.getCurrentState() == Player.STATE_COMPLETED) {
return getAction(player, R.drawable.ic_replay, return getAction(R.drawable.ic_replay,
R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE); R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
} else if (player.isPlaying() } else if (player.isPlaying()
|| player.getCurrentState() == Player.STATE_PREFLIGHT || player.getCurrentState() == Player.STATE_PREFLIGHT
|| player.getCurrentState() == Player.STATE_BLOCKED || player.getCurrentState() == Player.STATE_BLOCKED
|| player.getCurrentState() == Player.STATE_BUFFERING) { || player.getCurrentState() == Player.STATE_BUFFERING) {
return getAction(player, R.drawable.exo_notification_pause, return getAction(R.drawable.exo_notification_pause,
R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE); R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
} else { } else {
return getAction(player, R.drawable.exo_notification_play, return getAction(R.drawable.exo_notification_play,
R.string.exo_controls_play_description, ACTION_PLAY_PAUSE); R.string.exo_controls_play_description, ACTION_PLAY_PAUSE);
} }
case NotificationConstants.REPEAT: case NotificationConstants.REPEAT:
if (player.getRepeatMode() == REPEAT_MODE_ALL) { if (player.getRepeatMode() == REPEAT_MODE_ALL) {
return getAction(player, R.drawable.exo_media_action_repeat_all, return getAction(R.drawable.exo_media_action_repeat_all,
R.string.exo_controls_repeat_all_description, ACTION_REPEAT); R.string.exo_controls_repeat_all_description, ACTION_REPEAT);
} else if (player.getRepeatMode() == REPEAT_MODE_ONE) { } else if (player.getRepeatMode() == REPEAT_MODE_ONE) {
return getAction(player, R.drawable.exo_media_action_repeat_one, return getAction(R.drawable.exo_media_action_repeat_one,
R.string.exo_controls_repeat_one_description, ACTION_REPEAT); R.string.exo_controls_repeat_one_description, ACTION_REPEAT);
} else /* player.getRepeatMode() == REPEAT_MODE_OFF */ { } else /* player.getRepeatMode() == REPEAT_MODE_OFF */ {
return getAction(player, R.drawable.exo_media_action_repeat_off, return getAction(R.drawable.exo_media_action_repeat_off,
R.string.exo_controls_repeat_off_description, ACTION_REPEAT); R.string.exo_controls_repeat_off_description, ACTION_REPEAT);
} }
case NotificationConstants.SHUFFLE: case NotificationConstants.SHUFFLE:
if (player.getPlayQueue() != null && player.getPlayQueue().isShuffled()) { if (player.getPlayQueue() != null && player.getPlayQueue().isShuffled()) {
return getAction(player, R.drawable.exo_controls_shuffle_on, return getAction(R.drawable.exo_controls_shuffle_on,
R.string.exo_controls_shuffle_on_description, ACTION_SHUFFLE); R.string.exo_controls_shuffle_on_description, ACTION_SHUFFLE);
} else { } else {
return getAction(player, R.drawable.exo_controls_shuffle_off, return getAction(R.drawable.exo_controls_shuffle_off,
R.string.exo_controls_shuffle_off_description, ACTION_SHUFFLE); R.string.exo_controls_shuffle_off_description, ACTION_SHUFFLE);
} }
case NotificationConstants.CLOSE: case NotificationConstants.CLOSE:
return getAction(player, R.drawable.ic_close, return getAction(R.drawable.ic_close,
R.string.close, ACTION_CLOSE); R.string.close, ACTION_CLOSE);
case NotificationConstants.NOTHING: case NotificationConstants.NOTHING:
@ -324,8 +314,7 @@ public final class NotificationUtil {
} }
} }
private NotificationCompat.Action getAction(final Player player, private NotificationCompat.Action getAction(@DrawableRes final int drawable,
@DrawableRes final int drawable,
@StringRes final int title, @StringRes final int title,
final String intentAction) { final String intentAction) {
return new NotificationCompat.Action(drawable, player.getContext().getString(title), return new NotificationCompat.Action(drawable, player.getContext().getString(title),
@ -353,7 +342,7 @@ public final class NotificationUtil {
// BITMAP // BITMAP
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
private void setLargeIcon(final NotificationCompat.Builder builder, final Player player) { private void setLargeIcon(final NotificationCompat.Builder builder) {
final boolean scaleImageToSquareAspectRatio = player.getPrefs().getBoolean( final boolean scaleImageToSquareAspectRatio = player.getPrefs().getBoolean(
player.getContext().getString(R.string.scale_to_square_image_in_notifications_key), player.getContext().getString(R.string.scale_to_square_image_in_notifications_key),
false); false);

View File

@ -38,7 +38,6 @@ import static org.schabi.newpipe.player.PlayerService.ACTION_PLAY_PREVIOUS;
import static org.schabi.newpipe.player.PlayerService.ACTION_RECREATE_NOTIFICATION; import static org.schabi.newpipe.player.PlayerService.ACTION_RECREATE_NOTIFICATION;
import static org.schabi.newpipe.player.PlayerService.ACTION_REPEAT; import static org.schabi.newpipe.player.PlayerService.ACTION_REPEAT;
import static org.schabi.newpipe.player.PlayerService.ACTION_SHUFFLE; import static org.schabi.newpipe.player.PlayerService.ACTION_SHUFFLE;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE;
import static org.schabi.newpipe.player.helper.PlayerHelper.isPlaybackResumeEnabled; import static org.schabi.newpipe.player.helper.PlayerHelper.isPlaybackResumeEnabled;
import static org.schabi.newpipe.player.helper.PlayerHelper.nextRepeatMode; import static org.schabi.newpipe.player.helper.PlayerHelper.nextRepeatMode;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlaybackParametersFromPrefs; import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlaybackParametersFromPrefs;
@ -620,7 +619,7 @@ public final class Player implements PlaybackListener, Listener {
} }
private void setRecovery(final int queuePos, final long windowPos) { private void setRecovery(final int queuePos, final long windowPos) {
if (playQueue.size() <= queuePos) { if (playQueue == null || playQueue.size() <= queuePos) {
return; return;
} }
@ -735,9 +734,6 @@ public final class Player implements PlaybackListener, Listener {
case ACTION_SHUFFLE: case ACTION_SHUFFLE:
toggleShuffleModeEnabled(); toggleShuffleModeEnabled();
break; break;
case ACTION_RECREATE_NOTIFICATION:
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, true);
break;
case Intent.ACTION_CONFIGURATION_CHANGED: case Intent.ACTION_CONFIGURATION_CHANGED:
assureCorrectAppLanguage(service); assureCorrectAppLanguage(service);
if (DEBUG) { if (DEBUG) {
@ -797,8 +793,6 @@ public final class Player implements PlaybackListener, Listener {
} }
currentThumbnail = bitmap; currentThumbnail = bitmap;
NotificationUtil.getInstance()
.createNotificationIfNeededAndUpdate(Player.this, false);
// there is a new thumbnail, so changed the end screen thumbnail, too. // there is a new thumbnail, so changed the end screen thumbnail, too.
UIs.call(playerUi -> playerUi.onThumbnailLoaded(bitmap)); UIs.call(playerUi -> playerUi.onThumbnailLoaded(bitmap));
} }
@ -807,8 +801,7 @@ public final class Player implements PlaybackListener, Listener {
public void onBitmapFailed(final Exception e, final Drawable errorDrawable) { public void onBitmapFailed(final Exception e, final Drawable errorDrawable) {
Log.e(TAG, "Thumbnail - onBitmapFailed() called: url = [" + url + "]", e); Log.e(TAG, "Thumbnail - onBitmapFailed() called: url = [" + url + "]", e);
currentThumbnail = null; currentThumbnail = null;
NotificationUtil.getInstance() UIs.call(playerUi -> playerUi.onThumbnailLoaded(null));
.createNotificationIfNeededAndUpdate(Player.this, false);
} }
@Override @Override
@ -1082,8 +1075,6 @@ public final class Player implements PlaybackListener, Listener {
} }
UIs.call(PlayerUi::onBlocked); UIs.call(PlayerUi::onBlocked);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
private void onPlaying() { private void onPlaying() {
@ -1095,8 +1086,6 @@ public final class Player implements PlaybackListener, Listener {
} }
UIs.call(PlayerUi::onPlaying); UIs.call(PlayerUi::onPlaying);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
private void onBuffering() { private void onBuffering() {
@ -1105,10 +1094,6 @@ public final class Player implements PlaybackListener, Listener {
} }
UIs.call(PlayerUi::onBuffering); UIs.call(PlayerUi::onBuffering);
if (NotificationUtil.getInstance().shouldUpdateBufferingSlot()) {
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
}
} }
private void onPaused() { private void onPaused() {
@ -1121,24 +1106,13 @@ public final class Player implements PlaybackListener, Listener {
} }
UIs.call(PlayerUi::onPaused); UIs.call(PlayerUi::onPaused);
// Remove running notification when user does not want minimization to background or popup
if (PlayerHelper.getMinimizeOnExitAction(context) == MINIMIZE_ON_EXIT_MODE_NONE
&& videoPlayerSelected()) {
NotificationUtil.getInstance().cancelNotificationAndStopForeground(service);
} else {
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
}
} }
private void onPausedSeek() { private void onPausedSeek() {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onPausedSeek() called"); Log.d(TAG, "onPausedSeek() called");
} }
UIs.call(PlayerUi::onPausedSeek); UIs.call(PlayerUi::onPausedSeek);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
private void onCompleted() { private void onCompleted() {
@ -1150,7 +1124,6 @@ public final class Player implements PlaybackListener, Listener {
} }
UIs.call(PlayerUi::onCompleted); UIs.call(PlayerUi::onCompleted);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
if (playQueue.getIndex() < playQueue.size() - 1) { if (playQueue.getIndex() < playQueue.size() - 1) {
playQueue.offsetIndex(+1); playQueue.offsetIndex(+1);
@ -1190,7 +1163,7 @@ public final class Player implements PlaybackListener, Listener {
+ "repeatMode = [" + repeatMode + "]"); + "repeatMode = [" + repeatMode + "]");
} }
UIs.call(playerUi -> playerUi.onRepeatModeChanged(repeatMode)); UIs.call(playerUi -> playerUi.onRepeatModeChanged(repeatMode));
onShuffleOrRepeatModeChanged(); notifyPlaybackUpdateToListeners();
} }
@Override @Override
@ -1209,7 +1182,7 @@ public final class Player implements PlaybackListener, Listener {
} }
UIs.call(playerUi -> playerUi.onShuffleModeEnabledChanged(shuffleModeEnabled)); UIs.call(playerUi -> playerUi.onShuffleModeEnabledChanged(shuffleModeEnabled));
onShuffleOrRepeatModeChanged(); notifyPlaybackUpdateToListeners();
} }
public void toggleShuffleModeEnabled() { public void toggleShuffleModeEnabled() {
@ -1217,11 +1190,6 @@ public final class Player implements PlaybackListener, Listener {
simpleExoPlayer.setShuffleModeEnabled(!simpleExoPlayer.getShuffleModeEnabled()); simpleExoPlayer.setShuffleModeEnabled(!simpleExoPlayer.getShuffleModeEnabled());
} }
} }
private void onShuffleOrRepeatModeChanged() {
notifyPlaybackUpdateToListeners();
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
}
//endregion //endregion
@ -1806,12 +1774,15 @@ public final class Player implements PlaybackListener, Listener {
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
//region Metadata //region Metadata
private void onMetadataChanged(@NonNull final StreamInfo info) { private void updateMetadataWith(@NonNull final StreamInfo info) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Playback - onMetadataChanged() called, playing: " + info.getName()); Log.d(TAG, "Playback - onMetadataChanged() called, playing: " + info.getName());
} }
if (exoPlayerIsNull()) {
return;
}
UIs.call(playerUi -> playerUi.onMetadataChanged(info)); maybeAutoQueueNextStream(info);
initThumbnail(info.getThumbnailUrl()); initThumbnail(info.getThumbnailUrl());
registerStreamViewed(); registerStreamViewed();
@ -1826,17 +1797,7 @@ public final class Player implements PlaybackListener, Listener {
); );
notifyMetadataUpdateToListeners(); notifyMetadataUpdateToListeners();
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); UIs.call(playerUi -> playerUi.onMetadataChanged(info));
}
private void updateMetadataWith(@NonNull final StreamInfo streamInfo) {
if (exoPlayerIsNull()) {
return;
}
maybeAutoQueueNextStream(streamInfo);
onMetadataChanged(streamInfo);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, true);
} }
@NonNull @NonNull
@ -1925,7 +1886,6 @@ public final class Player implements PlaybackListener, Listener {
public void onPlayQueueEdited() { public void onPlayQueueEdited() {
notifyPlaybackUpdateToListeners(); notifyPlaybackUpdateToListeners();
UIs.call(PlayerUi::onPlayQueueEdited); UIs.call(PlayerUi::onPlayQueueEdited);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
@Override // own playback listener @Override // own playback listener

View File

@ -88,9 +88,6 @@ public final class PlayerService extends Service {
ThemeHelper.setTheme(this); ThemeHelper.setTheme(this);
player = new Player(this); player = new Player(this);
/*final MainPlayerUi mainPlayerUi = new MainPlayerUi(player,
PlayerBinding.inflate(LayoutInflater.from(this)));
player.UIs().add(mainPlayerUi);*/
} }
@Override @Override
@ -159,7 +156,6 @@ public final class PlayerService extends Service {
} }
public void stopService() { public void stopService() {
NotificationUtil.getInstance().cancelNotificationAndStopForeground(this);
cleanup(); cleanup();
stopSelf(); stopSelf();
} }

View File

@ -1,26 +1,125 @@
package org.schabi.newpipe.player.ui; package org.schabi.newpipe.player.ui;
import androidx.annotation.NonNull; import static org.schabi.newpipe.player.PlayerService.ACTION_RECREATE_NOTIFICATION;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE;
import android.content.Intent;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.Player.RepeatMode;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.NotificationUtil; import org.schabi.newpipe.player.NotificationUtil;
import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.Player;
import org.schabi.newpipe.player.helper.PlayerHelper;
public final class NotificationPlayerUi extends PlayerUi { public final class NotificationPlayerUi extends PlayerUi {
boolean foregroundNotificationAlreadyCreated = false; private boolean foregroundNotificationAlreadyCreated = false;
private final NotificationUtil notificationUtil;
public NotificationPlayerUi(@NonNull final Player player) { public NotificationPlayerUi(@NonNull final Player player) {
super(player); super(player);
notificationUtil = new NotificationUtil(player);
} }
@Override @Override
public void initPlayer() { public void initPlayer() {
super.initPlayer(); super.initPlayer();
if (!foregroundNotificationAlreadyCreated) { if (!foregroundNotificationAlreadyCreated) {
NotificationUtil.getInstance() notificationUtil.createNotificationAndStartForeground();
.createNotificationAndStartForeground(player, player.getService());
foregroundNotificationAlreadyCreated = true; foregroundNotificationAlreadyCreated = true;
} }
} }
// TODO TODO on destroy remove foreground @Override
public void destroy() {
super.destroy();
notificationUtil.cancelNotificationAndStopForeground();
}
@Override
public void onThumbnailLoaded(@Nullable final Bitmap bitmap) {
super.onThumbnailLoaded(bitmap);
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onBlocked() {
super.onBlocked();
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onPlaying() {
super.onPlaying();
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onBuffering() {
super.onBuffering();
if (notificationUtil.shouldUpdateBufferingSlot()) {
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
}
@Override
public void onPaused() {
super.onPaused();
// Remove running notification when user does not want minimization to background or popup
if (PlayerHelper.getMinimizeOnExitAction(context) == MINIMIZE_ON_EXIT_MODE_NONE
&& player.videoPlayerSelected()) {
notificationUtil.cancelNotificationAndStopForeground();
} else {
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
}
@Override
public void onPausedSeek() {
super.onPausedSeek();
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onCompleted() {
super.onCompleted();
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onRepeatModeChanged(@RepeatMode final int repeatMode) {
super.onRepeatModeChanged(repeatMode);
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onShuffleModeEnabledChanged(final boolean shuffleModeEnabled) {
super.onShuffleModeEnabledChanged(shuffleModeEnabled);
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
@Override
public void onBroadcastReceived(final Intent intent) {
super.onBroadcastReceived(intent);
if (ACTION_RECREATE_NOTIFICATION.equals(intent.getAction())) {
notificationUtil.createNotificationIfNeededAndUpdate(true);
}
}
@Override
public void onMetadataChanged(@NonNull final StreamInfo info) {
super.onMetadataChanged(info);
notificationUtil.createNotificationIfNeededAndUpdate(true);
}
@Override
public void onPlayQueueEdited() {
super.onPlayQueueEdited();
notificationUtil.createNotificationIfNeededAndUpdate(false);
}
} }