reduce number of notification updates

Issue: #6657
PiperOrigin-RevId: 283563218
This commit is contained in:
bachinger 2019-12-03 17:42:48 +00:00 committed by Oliver Woodman
parent e595791245
commit 5171a4bf5e

View File

@ -25,6 +25,7 @@ import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message;
import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.MediaSessionCompat;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
@ -52,7 +53,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
/** /**
* A notification manager to start, update and cancel a media style notification reflecting the * A notification manager to start, update and cancel a media style notification reflecting the
@ -269,14 +269,7 @@ public class PlayerNotificationManager {
*/ */
public void onBitmap(final Bitmap bitmap) { public void onBitmap(final Bitmap bitmap) {
if (bitmap != null) { if (bitmap != null) {
mainHandler.post( postUpdateNotificationBitmap(bitmap, notificationTag);
() -> {
if (player != null
&& notificationTag == currentNotificationTag
&& isNotificationStarted) {
startOrUpdateNotification(bitmap);
}
});
} }
} }
} }
@ -303,6 +296,11 @@ public class PlayerNotificationManager {
*/ */
private static final String ACTION_DISMISS = "com.google.android.exoplayer.dismiss"; private static final String ACTION_DISMISS = "com.google.android.exoplayer.dismiss";
// Internal messages.
private static final int MSG_START_OR_UPDATE_NOTIFICATION = 0;
private static final int MSG_UPDATE_NOTIFICATION_BITMAP = 1;
/** /**
* Visibility of notification on the lock screen. One of {@link * Visibility of notification on the lock screen. One of {@link
* NotificationCompat#VISIBILITY_PRIVATE}, {@link NotificationCompat#VISIBILITY_PUBLIC} or {@link * NotificationCompat#VISIBILITY_PRIVATE}, {@link NotificationCompat#VISIBILITY_PUBLIC} or {@link
@ -598,7 +596,10 @@ public class PlayerNotificationManager {
controlDispatcher = new DefaultControlDispatcher(); controlDispatcher = new DefaultControlDispatcher();
window = new Timeline.Window(); window = new Timeline.Window();
instanceId = instanceIdCounter++; instanceId = instanceIdCounter++;
mainHandler = new Handler(Looper.getMainLooper()); //noinspection Convert2MethodRef
mainHandler =
Util.createHandler(
Looper.getMainLooper(), msg -> PlayerNotificationManager.this.handleMessage(msg));
notificationManager = NotificationManagerCompat.from(context); notificationManager = NotificationManagerCompat.from(context);
playerListener = new PlayerListener(); playerListener = new PlayerListener();
notificationBroadcastReceiver = new NotificationBroadcastReceiver(); notificationBroadcastReceiver = new NotificationBroadcastReceiver();
@ -662,7 +663,7 @@ public class PlayerNotificationManager {
this.player = player; this.player = player;
if (player != null) { if (player != null) {
player.addListener(playerListener); player.addListener(playerListener);
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
} }
@ -945,26 +946,17 @@ public class PlayerNotificationManager {
/** Forces an update of the notification if already started. */ /** Forces an update of the notification if already started. */
public void invalidate() { public void invalidate() {
if (isNotificationStarted && player != null) { if (isNotificationStarted) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
} }
@Nullable private void startOrUpdateNotification(Player player, @Nullable Bitmap bitmap) {
private Notification startOrUpdateNotification() {
Assertions.checkNotNull(this.player);
return startOrUpdateNotification(/* bitmap= */ null);
}
@RequiresNonNull("player")
@Nullable
private Notification startOrUpdateNotification(@Nullable Bitmap bitmap) {
Player player = this.player;
boolean ongoing = getOngoing(player); boolean ongoing = getOngoing(player);
builder = createNotification(player, builder, ongoing, bitmap); builder = createNotification(player, builder, ongoing, bitmap);
if (builder == null) { if (builder == null) {
stopNotification(/* dismissedByUser= */ false); stopNotification(/* dismissedByUser= */ false);
return null; return;
} }
Notification notification = builder.build(); Notification notification = builder.build();
notificationManager.notify(notificationId, notification); notificationManager.notify(notificationId, notification);
@ -975,16 +967,16 @@ public class PlayerNotificationManager {
notificationListener.onNotificationStarted(notificationId, notification); notificationListener.onNotificationStarted(notificationId, notification);
} }
} }
NotificationListener listener = notificationListener; @Nullable NotificationListener listener = notificationListener;
if (listener != null) { if (listener != null) {
listener.onNotificationPosted(notificationId, notification, ongoing); listener.onNotificationPosted(notificationId, notification, ongoing);
} }
return notification;
} }
private void stopNotification(boolean dismissedByUser) { private void stopNotification(boolean dismissedByUser) {
if (isNotificationStarted) { if (isNotificationStarted) {
isNotificationStarted = false; isNotificationStarted = false;
mainHandler.removeMessages(MSG_START_OR_UPDATE_NOTIFICATION);
notificationManager.cancel(notificationId); notificationManager.cancel(notificationId);
context.unregisterReceiver(notificationBroadcastReceiver); context.unregisterReceiver(notificationBroadcastReceiver);
if (notificationListener != null) { if (notificationListener != null) {
@ -1261,6 +1253,37 @@ public class PlayerNotificationManager {
&& player.getPlayWhenReady(); && player.getPlayWhenReady();
} }
private void postStartOrUpdateNotification() {
if (!mainHandler.hasMessages(MSG_START_OR_UPDATE_NOTIFICATION)) {
mainHandler.sendEmptyMessage(MSG_START_OR_UPDATE_NOTIFICATION);
}
}
private void postUpdateNotificationBitmap(Bitmap bitmap, int notificationTag) {
mainHandler
.obtainMessage(
MSG_UPDATE_NOTIFICATION_BITMAP, notificationTag, C.INDEX_UNSET /* ignored */, bitmap)
.sendToTarget();
}
private boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_START_OR_UPDATE_NOTIFICATION:
if (player != null) {
startOrUpdateNotification(player, /* bitmap= */ null);
}
break;
case MSG_UPDATE_NOTIFICATION_BITMAP:
if (player != null && isNotificationStarted && currentNotificationTag == msg.arg1) {
startOrUpdateNotification(player, (Bitmap) msg.obj);
}
break;
default:
return false;
}
return true;
}
private static Map<String, NotificationCompat.Action> createPlaybackActions( private static Map<String, NotificationCompat.Action> createPlaybackActions(
Context context, int instanceId) { Context context, int instanceId) {
Map<String, NotificationCompat.Action> actions = new HashMap<>(); Map<String, NotificationCompat.Action> actions = new HashMap<>();
@ -1326,37 +1349,37 @@ public class PlayerNotificationManager {
@Override @Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) { public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
@Override @Override
public void onIsPlayingChanged(boolean isPlaying) { public void onIsPlayingChanged(boolean isPlaying) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
@Override @Override
public void onTimelineChanged(Timeline timeline, int reason) { public void onTimelineChanged(Timeline timeline, int reason) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
@Override @Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
@Override @Override
public void onPositionDiscontinuity(int reason) { public void onPositionDiscontinuity(int reason) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
@Override @Override
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) { public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
@Override @Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
startOrUpdateNotification(); postStartOrUpdateNotification();
} }
} }