Move all notification-related calls to NotificationPlayerUi
This commit is contained in:
parent
b3f99645a3
commit
0bba1d95de
4 changed files with 155 additions and 111 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue