From 17e88f17498234f50ea58ba22bc8c6ab72d6d673 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 29 Dec 2023 15:08:44 +0100 Subject: [PATCH] Do not update notification actions if nothing changed This should avoid costly updates of the media session. --- .../mediasession/MediaSessionPlayerUi.java | 45 ++++++++++++------- .../notification/NotificationActionData.java | 17 ++++++- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java index 53d6c297a..737ebc5dd 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java @@ -28,9 +28,11 @@ import org.schabi.newpipe.player.ui.PlayerUi; import org.schabi.newpipe.player.ui.VideoPlayerUi; import org.schabi.newpipe.util.StreamTypeUtil; -import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class MediaSessionPlayerUi extends PlayerUi implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -42,6 +44,10 @@ public class MediaSessionPlayerUi extends PlayerUi private final String ignoreHardwareMediaButtonsKey; private boolean shouldIgnoreHardwareMediaButtons = false; + // used to check whether any notification action changed, before sending costly updates + private List prevNotificationActions = List.of(); + + public MediaSessionPlayerUi(@NonNull final Player player) { super(player); ignoreHardwareMediaButtonsKey = @@ -71,6 +77,10 @@ public class MediaSessionPlayerUi extends PlayerUi sessionConnector.setMetadataDeduplicationEnabled(true); sessionConnector.setMediaMetadataProvider(exoPlayer -> buildMediaMetadata()); + + // force updating media session actions by resetting the previous ones + prevNotificationActions = List.of(); + updateMediaSessionActions(); } @Override @@ -88,6 +98,7 @@ public class MediaSessionPlayerUi extends PlayerUi mediaSession.release(); mediaSession = null; } + prevNotificationActions = List.of(); } @Override @@ -187,23 +198,25 @@ public class MediaSessionPlayerUi extends PlayerUi return; } - final List actions = new ArrayList<>(2); - for (int i = 3; i < 5; ++i) { - // only use the fourth and fifth actions (the settings page also shows only the last 2) - final int action = player.getPrefs().getInt( - player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]), - NotificationConstants.SLOT_DEFAULTS[i]); + // only use the fourth and fifth actions (the settings page also shows only the last 2 on + // Android 13+) + final List newNotificationActions = IntStream.of(3, 4) + .map(i -> player.getPrefs().getInt( + player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]), + NotificationConstants.SLOT_DEFAULTS[i])) + .mapToObj(action -> NotificationActionData + .fromNotificationActionEnum(player, action)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - @Nullable final NotificationActionData data = - NotificationActionData.fromNotificationActionEnum(player, action); - - if (data != null) { - actions.add(new SessionConnectorActionProvider(data, context)); - } + // avoid costly notification actions update, if nothing changed from last time + if (!newNotificationActions.equals(prevNotificationActions)) { + prevNotificationActions = newNotificationActions; + sessionConnector.setCustomActionProviders( + newNotificationActions.stream() + .map(data -> new SessionConnectorActionProvider(data, context)) + .toArray(SessionConnectorActionProvider[]::new)); } - - sessionConnector.setCustomActionProviders( - actions.toArray(new MediaSessionConnector.CustomActionProvider[0])); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java index fd5e03bf1..98ee3d7b8 100644 --- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java +++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java @@ -20,6 +20,8 @@ import androidx.annotation.Nullable; import org.schabi.newpipe.R; import org.schabi.newpipe.player.Player; +import java.util.Objects; + public final class NotificationActionData { @Nullable private final String action; @@ -50,7 +52,6 @@ public final class NotificationActionData { return icon; } - @Nullable public static NotificationActionData fromNotificationActionEnum( @NonNull final Player player, @@ -165,4 +166,18 @@ public final class NotificationActionData { return null; } } + + + @Override + public boolean equals(@Nullable final Object obj) { + return (obj instanceof NotificationActionData other) + && Objects.equals(this.action, other.action) + && this.name.equals(other.name) + && this.icon == other.icon; + } + + @Override + public int hashCode() { + return Objects.hash(action, name, icon); + } }