From 9f005b508ad8ade416204d5fd86c0730e9b1ffa2 Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Tue, 30 Apr 2019 17:14:47 +0000 Subject: [PATCH] Hide our own media notification for Spotify when Spotify is running on the phone --- .../MprisPlugin/MprisMediaSession.java | 140 +++++++++++++----- .../Plugins/MprisPlugin/MprisPlugin.java | 2 +- 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java index 30ebd8e3..d710e917 100644 --- a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java +++ b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . -*/ + */ package org.kde.kdeconnect.Plugins.MprisPlugin; @@ -31,17 +31,21 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.preference.PreferenceManager; +import android.service.notification.StatusBarNotification; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; +import android.util.Pair; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Helpers.NotificationHelper; +import org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationReceiver; import org.kde.kdeconnect_tp.R; import java.util.HashSet; +import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.app.TaskStackBuilder; import androidx.media.app.NotificationCompat.MediaStyle; @@ -54,12 +58,14 @@ import androidx.media.app.NotificationCompat.MediaStyle; * - The media session (via MediaSessionCompat; for lock screen control on * older Android version. And in the future for lock screen album covers) */ -public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceChangeListener { +public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceChangeListener, NotificationReceiver.NotificationListener { private final static int MPRIS_MEDIA_NOTIFICATION_ID = 0x91b70463; // echo MprisNotification | md5sum | head -c 8 private final static String MPRIS_MEDIA_SESSION_TAG = "org.kde.kdeconnect_tp.media_session"; private static final MprisMediaSession instance = new MprisMediaSession(); + private boolean spotifyRunning; + public static MprisMediaSession getInstance() { return instance; } @@ -132,6 +138,19 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh mpris.setPlayerListUpdatedHandler("media_notification", mediaNotificationHandler); mpris.setPlayerStatusUpdatedHandler("media_notification", mediaNotificationHandler); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + NotificationReceiver.RunCommand(context, service -> { + + service.addListener(MprisMediaSession.this); + + boolean serviceReady = service.isConnected(); + + if (serviceReady) { + onListenerConnected(service); + } + }); + } + updateMediaNotification(); } @@ -164,52 +183,62 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh * @param service The background service */ private void updateCurrentPlayer(BackgroundService service) { - Device device = null; - MprisPlugin.MprisPlayer playing = null; + Pair player = findPlayer(service); + //Update the last-displayed device and player + notificationDevice = player.first == null ? null : player.first.getDeviceId(); + notificationPlayer = player.second; + } + + private Pair findPlayer(BackgroundService service) { //First try the previously displayed player - if (notificationDevice != null && mprisDevices.contains(notificationDevice) && notificationPlayer != null) { - device = service.getDevice(notificationDevice); - } - MprisPlugin mpris = null; - if (device != null) { - mpris = device.getPlugin(MprisPlugin.class); - } - if (mpris != null) { - playing = mpris.getPlayerStatus(notificationPlayer.getPlayer()); - } + if (notificationDevice != null && mprisDevices.contains(notificationDevice)) { + Device device = service.getDevice(notificationDevice); - //If nonexistant or not playing, try a different player for the same device - if ((playing == null || !playing.isPlaying()) && mpris != null) { - MprisPlugin.MprisPlayer playingPlayer = mpris.getPlayingPlayer(); + if (device != null && device.isPluginEnabled("MprisPlugin")) { + if (shouldShowPlayer(notificationPlayer) && notificationPlayer.isPlaying()){ + return new Pair<>(device, notificationPlayer); + } - //Only replace the previously found player if we really found one - if (playingPlayer != null) { - playing = playingPlayer; - } - } - - //If nonexistant or not playing, try a different player for another device - if (playing == null || !playing.isPlaying()) { - for (Device otherDevice : service.getDevices().values()) { - //First, check if we actually display notification for this device - if (!mprisDevices.contains(otherDevice.getDeviceId())) continue; - mpris = otherDevice.getPlugin(MprisPlugin.class); - if (mpris == null) continue; - - MprisPlugin.MprisPlayer playingPlayer = mpris.getPlayingPlayer(); - //Only replace the previously found player if we really found one - if (playingPlayer != null) { - playing = playingPlayer; - device = otherDevice; - break; + // Try a different player for the same device + MprisPlugin.MprisPlayer player = getPlayerFromDevice(device); + if (player != null) { + return new Pair<>(device, player); } } } - //Update the last-displayed device and player - notificationDevice = device == null ? null : device.getDeviceId(); - notificationPlayer = playing; + // Try a different player from another device + for (Device otherDevice : service.getDevices().values()) { + MprisPlugin.MprisPlayer player = getPlayerFromDevice(otherDevice); + if (player != null) { + return new Pair<>(otherDevice, player); + } + } + return new Pair<>(null, null); + } + + private MprisPlugin.MprisPlayer getPlayerFromDevice(Device device) { + + if (!mprisDevices.contains(device.getDeviceId())) + return null; + + MprisPlugin plugin = device.getPlugin(MprisPlugin.class); + + if (plugin == null) { + return null; + } + + MprisPlugin.MprisPlayer player = plugin.getPlayingPlayer(); + if (shouldShowPlayer(player)) { + return player; + } + + return null; + } + + private boolean shouldShowPlayer(MprisPlugin.MprisPlayer player) { + return player != null && !(player.isSpotify() && spotifyRunning); } /** @@ -316,7 +345,7 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh */ PendingIntent piOpenActivity = TaskStackBuilder.create(context) .addNextIntentWithParentStack(iOpenActivity) - .getPendingIntent(Build.VERSION.SDK_INT > 15 ? 0 : (int)System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT); + .getPendingIntent(Build.VERSION.SDK_INT > 15 ? 0 : (int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder notification = new NotificationCompat.Builder(context, NotificationHelper.Channels.MEDIA_CONTROL); @@ -433,4 +462,33 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh notificationPlayer = player; updateMediaNotification(); } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) + @Override + public void onNotificationPosted(StatusBarNotification n) { + if (n.getPackageName().equals("com.spotify.music")) { + spotifyRunning = true; + updateMediaNotification(); + } + } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) + @Override + public void onNotificationRemoved(StatusBarNotification n) { + if (n.getPackageName().equals("com.spotify.music")) { + spotifyRunning = false; + updateMediaNotification(); + } + } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) + @Override + public void onListenerConnected(NotificationReceiver service) { + for (StatusBarNotification n : service.getActiveNotifications()) { + if (n.getPackageName().equals("com.spotify.music")) { + spotifyRunning = true; + updateMediaNotification(); + } + } + } } diff --git a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java index d60c7b69..30fe977e 100644 --- a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java @@ -87,7 +87,7 @@ public class MprisPlugin extends Plugin { return player; } - private boolean isSpotify() { + boolean isSpotify() { return getPlayer().toLowerCase().equals("spotify"); }