Make notification creation and cancelling more consistent

This commit is contained in:
Stypox 2020-09-08 21:19:43 +02:00
parent 71b32fe641
commit 9cf0bc6c82
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
3 changed files with 39 additions and 55 deletions

View File

@ -121,7 +121,7 @@ public final class MainPlayer extends Service {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
|| intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) { || intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) {
showNotificationAndStartForeground(); NotificationUtil.getInstance().createNotificationAndStartForeground(playerImpl, this);
} }
playerImpl.handleIntent(intent); playerImpl.handleIntent(intent);
@ -154,7 +154,7 @@ public final class MainPlayer extends Service {
// So we should hide the notification at all. // So we should hide the notification at all.
// When autoplay enabled such notification flashing is annoying so skip this case // When autoplay enabled such notification flashing is annoying so skip this case
if (!autoplayEnabled) { if (!autoplayEnabled) {
stopForeground(true); NotificationUtil.getInstance().cancelNotificationAndStopForeground(this);
} }
} }
} }
@ -202,9 +202,8 @@ public final class MainPlayer extends Service {
playerImpl.removePopupFromView(); playerImpl.removePopupFromView();
playerImpl.destroy(); playerImpl.destroy();
} }
NotificationUtil.getInstance().cancelNotification();
stopForeground(true); NotificationUtil.getInstance().cancelNotificationAndStopForeground(this);
stopSelf(); stopSelf();
} }
@ -243,11 +242,6 @@ public final class MainPlayer extends Service {
} }
} }
private void showNotificationAndStartForeground() {
NotificationUtil.getInstance().createNotificationIfNeeded(playerImpl, true);
NotificationUtil.getInstance().startForegroundServiceWithNotification(this);
}
public class LocalBinder extends Binder { public class LocalBinder extends Binder {

View File

@ -42,7 +42,7 @@ import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE;
* @author cool-student * @author cool-student
*/ */
public final class NotificationUtil { public final class NotificationUtil {
private static final String TAG = "NotificationUtil"; private static final String TAG = NotificationUtil.class.getSimpleName();
private static final boolean DEBUG = BasePlayer.DEBUG; private static final boolean DEBUG = BasePlayer.DEBUG;
private static final int NOTIFICATION_ID = 123789; private static final int NOTIFICATION_ID = 123789;
@ -70,21 +70,25 @@ public final class NotificationUtil {
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/** /**
* Creates the notification if it does not exist already or unless forceRecreate is true. * 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.
* @param player the player currently open, to take data from * @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
*/ */
void createNotificationIfNeeded(final VideoPlayerImpl player, final boolean forceRecreate) { synchronized void createNotificationIfNeededAndUpdate(final VideoPlayerImpl player,
final boolean forceRecreate) {
if (notificationBuilder == null || forceRecreate) { if (notificationBuilder == null || forceRecreate) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "N_ createNotificationIfNeeded(true)"); Log.d(TAG, "N_ createNotificationIfNeededAndUpdate(true)");
} }
notificationBuilder = createNotification(player); notificationBuilder = createNotification(player);
} }
updateNotification(player);
} }
private NotificationCompat.Builder createNotification(final VideoPlayerImpl player) { private synchronized NotificationCompat.Builder createNotification(
final VideoPlayerImpl player) {
notificationManager = notificationManager =
(NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context,
@ -115,17 +119,12 @@ public final class NotificationUtil {
.setPriority(NotificationCompat.PRIORITY_HIGH) .setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(R.drawable.ic_newpipe_triangle_white) .setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(player.getVideoTitle())
.setContentText(player.getUploaderName())
.setColor(ContextCompat.getColor(player.context, R.color.gray)) .setColor(ContextCompat.getColor(player.context, R.color.gray))
.setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID,
getIntentForNotification(player), FLAG_UPDATE_CURRENT)) getIntentForNotification(player), FLAG_UPDATE_CURRENT))
.setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, .setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID,
new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)); new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT));
updateActions(builder, player);
setLargeIcon(builder, player);
return builder; return builder;
} }
@ -133,7 +132,7 @@ public final class NotificationUtil {
* Updates the notification and the button icons depending on the playback state. * Updates the notification and the button icons depending on the playback state.
* @param player the player currently open, to take data from * @param player the player currently open, to take data from
*/ */
synchronized void updateNotification(final VideoPlayerImpl player) { private synchronized void updateNotification(final VideoPlayerImpl player) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "N_ updateNotification()"); Log.d(TAG, "N_ updateNotification()");
} }
@ -151,7 +150,15 @@ public final class NotificationUtil {
} }
void startForegroundServiceWithNotification(final Service service) { boolean hasSlotWithBuffering() {
return notificationSlots[1] == NotificationConstants.PLAY_PAUSE_BUFFERING
|| notificationSlots[2] == NotificationConstants.PLAY_PAUSE_BUFFERING;
}
void createNotificationAndStartForeground(final VideoPlayerImpl player, final Service service) {
createNotificationIfNeededAndUpdate(player, true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
service.startForeground(NOTIFICATION_ID, notificationBuilder.build(), service.startForeground(NOTIFICATION_ID, notificationBuilder.build(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK); ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
@ -160,13 +167,7 @@ public final class NotificationUtil {
} }
} }
void cancelNotificationAndStopForeground(final Service service) {
boolean hasSlotWithBuffering() {
return notificationSlots[1] == NotificationConstants.PLAY_PAUSE_BUFFERING
|| notificationSlots[2] == NotificationConstants.PLAY_PAUSE_BUFFERING;
}
void cancelNotification() {
try { try {
if (notificationManager != null) { if (notificationManager != null) {
notificationManager.cancel(NOTIFICATION_ID); notificationManager.cancel(NOTIFICATION_ID);
@ -176,6 +177,8 @@ public final class NotificationUtil {
} }
notificationManager = null; notificationManager = null;
notificationBuilder = null; notificationBuilder = null;
service.stopForeground(true);
} }

View File

@ -575,7 +575,7 @@ public class VideoPlayerImpl extends VideoPlayer
void onShuffleOrRepeatModeChanged() { void onShuffleOrRepeatModeChanged() {
updatePlaybackButtons(); updatePlaybackButtons();
updatePlayback(); updatePlayback();
resetNotification(false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
@Override @Override
@ -612,7 +612,7 @@ public class VideoPlayerImpl extends VideoPlayer
titleTextView.setText(tag.getMetadata().getName()); titleTextView.setText(tag.getMetadata().getName());
channelTextView.setText(tag.getMetadata().getUploaderName()); channelTextView.setText(tag.getMetadata().getUploaderName());
resetNotification(false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
updateMetadata(); updateMetadata();
} }
@ -1059,9 +1059,7 @@ public class VideoPlayerImpl extends VideoPlayer
animatePlayButtons(false, 100); animatePlayButtons(false, 100);
getRootView().setKeepScreenOn(false); getRootView().setKeepScreenOn(false);
NotificationUtil.getInstance().createNotificationIfNeeded(this, false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
NotificationUtil.getInstance().updateNotification(
this);
} }
@Override @Override
@ -1077,7 +1075,7 @@ public class VideoPlayerImpl extends VideoPlayer
isForwardPressed = false; isForwardPressed = false;
isRewindPressed = false; isRewindPressed = false;
} else { } else {
NotificationUtil.getInstance().updateNotification(this); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
} }
} }
@ -1097,7 +1095,7 @@ public class VideoPlayerImpl extends VideoPlayer
checkLandscape(); checkLandscape();
getRootView().setKeepScreenOn(true); getRootView().setKeepScreenOn(true);
resetNotification(false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
@Override @Override
@ -1113,12 +1111,12 @@ public class VideoPlayerImpl extends VideoPlayer
updateWindowFlags(IDLE_WINDOW_FLAGS); updateWindowFlags(IDLE_WINDOW_FLAGS);
resetNotification(false);
// Remove running notification when user don't want music (or video in popup) // Remove running notification when user don't want music (or video in popup)
// to be played in background // to be played in background
if (!minimizeOnPopupEnabled() && !backgroundPlaybackEnabled() && videoPlayerSelected()) { if (!minimizeOnPopupEnabled() && !backgroundPlaybackEnabled() && videoPlayerSelected()) {
service.stopForeground(true); NotificationUtil.getInstance().cancelNotificationAndStopForeground(service);
} else {
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
getRootView().setKeepScreenOn(false); getRootView().setKeepScreenOn(false);
@ -1130,9 +1128,7 @@ public class VideoPlayerImpl extends VideoPlayer
animatePlayButtons(false, 100); animatePlayButtons(false, 100);
getRootView().setKeepScreenOn(true); getRootView().setKeepScreenOn(true);
NotificationUtil.getInstance().createNotificationIfNeeded(this, false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
NotificationUtil.getInstance().updateNotification(
this);
} }
@ -1146,9 +1142,7 @@ public class VideoPlayerImpl extends VideoPlayer
getRootView().setKeepScreenOn(false); getRootView().setKeepScreenOn(false);
updateWindowFlags(IDLE_WINDOW_FLAGS); updateWindowFlags(IDLE_WINDOW_FLAGS);
NotificationUtil.getInstance().createNotificationIfNeeded(this, false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
NotificationUtil.getInstance().updateNotification(this);
super.onCompleted(); super.onCompleted();
} }
@ -1239,7 +1233,7 @@ public class VideoPlayerImpl extends VideoPlayer
onShuffleClicked(); onShuffleClicked();
break; break;
case ACTION_RECREATE_NOTIFICATION: case ACTION_RECREATE_NOTIFICATION:
resetNotification(true); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, true);
break; break;
case Intent.ACTION_HEADSET_PLUG: //FIXME case Intent.ACTION_HEADSET_PLUG: //FIXME
/*notificationManager.cancel(NOTIFICATION_ID); /*notificationManager.cancel(NOTIFICATION_ID);
@ -1309,19 +1303,12 @@ public class VideoPlayerImpl extends VideoPlayer
// Thumbnail Loading // Thumbnail Loading
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
void resetNotification(final boolean recreate) {
NotificationUtil.getInstance().createNotificationIfNeeded(this, recreate);
NotificationUtil.getInstance().updateNotification(this);
}
@Override @Override
public void onLoadingComplete(final String imageUri, public void onLoadingComplete(final String imageUri,
final View view, final View view,
final Bitmap loadedImage) { final Bitmap loadedImage) {
// rebuild OLD notification here since remote view does not release bitmaps,
// causing memory leaks
super.onLoadingComplete(imageUri, view, loadedImage); super.onLoadingComplete(imageUri, view, loadedImage);
resetNotification(true); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
@Override @Override
@ -1329,13 +1316,13 @@ public class VideoPlayerImpl extends VideoPlayer
final View view, final View view,
final FailReason failReason) { final FailReason failReason) {
super.onLoadingFailed(imageUri, view, failReason); super.onLoadingFailed(imageUri, view, failReason);
resetNotification(true); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
@Override @Override
public void onLoadingCancelled(final String imageUri, final View view) { public void onLoadingCancelled(final String imageUri, final View view) {
super.onLoadingCancelled(imageUri, view); super.onLoadingCancelled(imageUri, view);
resetNotification(true); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////