From kde-commits Thu Nov 30 23:39:36 2017 From: Aleix Pol Date: Thu, 30 Nov 2017 23:39:36 +0000 To: kde-commits Subject: [kdeconnect-android] src/org/kde/kdeconnect/Plugins/MprisPlugin: Make the player status a per-player Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=151208518716347 Git commit cc8330a079a17ef99cdf9ba4feab4f88fe8465f8 by Aleix Pol, on behalf= of Matthijs Tijink. Committed on 30/11/2017 at 23:36. Pushed by apol into branch 'master'. Make the player status a per-player object in the MPRIS plugin Summary: This directly fixes a couple of bugs (where the UI was not updated in all c= ases) and will allow different code parts to use different players without = clashing with each other. This is required for sensible behaviour while using the media control notif= ication (which I plan to work on). Reviewers: #kde_connect, thomasp, albertvaka Reviewed By: #kde_connect, thomasp, albertvaka Subscribers: albertvaka, apol, thomasp Differential Revision: https://phabricator.kde.org/D8942 M +82 -120 src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisActivity.java M +185 -128 src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java https://commits.kde.org/kdeconnect-android/cc8330a079a17ef99cdf9ba4feab4f88= fe8465f8 diff --git a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisActivity.java = b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisActivity.java index 3fabd6e..4feb947 100644 --- a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisActivity.java +++ b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisActivity.java @@ -51,7 +51,7 @@ public class MprisActivity extends ActionBarActivity { private String deviceId; private final Handler positionSeekUpdateHandler =3D new Handler(); private Runnable positionSeekUpdateRunnable =3D null; - private String targetPlayer =3D null; + private MprisPlugin.MprisPlayer targetPlayer =3D null; = private static String milisToProgress(long milis) { int length =3D (int)(milis / 1000); //From milis to seconds @@ -69,7 +69,7 @@ public class MprisActivity extends ActionBarActivity { text.append(seconds); return text.toString(); } - protected void connectToPlugin() { + protected void connectToPlugin(final String targetPlayerName) { = BackgroundService.RunCommand(this, new BackgroundService.InstanceC= allback() { @Override @@ -81,6 +81,7 @@ public class MprisActivity extends ActionBarActivity { Log.e("MprisActivity", "device has no mpris plugin!"); return; } + targetPlayer =3D mpris.getPlayerStatus(targetPlayerName); = mpris.setPlayerStatusUpdatedHandler("activity", new Handle= r() { @Override @@ -88,49 +89,7 @@ public class MprisActivity extends ActionBarActivity { runOnUiThread(new Runnable() { @Override public void run() { - String song =3D mpris.getCurrentSong(); - - TextView nowPlaying =3D (TextView) findVie= wById(R.id.now_playing_textview); - if (!nowPlaying.getText().toString().equal= s(song)) { - nowPlaying.setText(song); - } - - //Hacks for Spotify because it reports inc= orrect info about what it supports - boolean isSpotify =3D "spotify".equals(mpr= is.getPlayer().toLowerCase()); - - if (mpris.getLength() > -1 && mpris.getPos= ition() > -1 && !isSpotify) { - ((TextView) findViewById(R.id.time_tex= tview)).setText(milisToProgress(mpris.getLength())); - SeekBar positionSeek =3D (SeekBar)find= ViewById(R.id.positionSeek); - positionSeek.setMax((int)(mpris.getLen= gth())); - positionSeek.setProgress((int)(mpris.g= etPosition())); - findViewById(R.id.progress_slider).set= Visibility(View.VISIBLE); - } else { - findViewById(R.id.progress_slider).set= Visibility(View.GONE); - } - - int volume =3D mpris.getVolume(); - ((SeekBar) findViewById(R.id.volume_seek))= .setProgress(volume); - - boolean isPlaying =3D mpris.isPlaying(); - if (isPlaying) { - ((ImageButton) findViewById(R.id.play_= button)).setImageResource(android.R.drawable.ic_media_pause); - findViewById(R.id.play_button).setVisi= bility(mpris.isPauseAllowed() ? View.VISIBLE : View.GONE); - } else { - ((ImageButton) findViewById(R.id.play_= button)).setImageResource(android.R.drawable.ic_media_play); - findViewById(R.id.play_button).setVisi= bility(mpris.isPlayAllowed() ? View.VISIBLE : View.GONE); - } - - if (isSpotify) { - findViewById(R.id.volume_layout).setVi= sibility(View.INVISIBLE); - findViewById(R.id.rew_button).setVisib= ility(View.GONE); - findViewById(R.id.ff_button).setVisibi= lity(View.GONE); - } else { - findViewById(R.id.volume_layout).setVi= sibility(View.VISIBLE); - findViewById(R.id.rew_button).setVisib= ility(mpris.isSeekAllowed() ? View.VISIBLE : View.GONE); - findViewById(R.id.ff_button).setVisibi= lity(mpris.isSeekAllowed() ? View.VISIBLE : View.GONE); - } - findViewById(R.id.next_button).setVisibili= ty(mpris.isGoNextAllowed() ? View.VISIBLE : View.GONE); - findViewById(R.id.prev_button).setVisibili= ty(mpris.isGoPreviousAllowed() ? View.VISIBLE : View.GONE); + updatePlayerStatus(mpris); } }); } @@ -169,36 +128,28 @@ public class MprisActivity extends ActionBarActivity { if (pos >=3D playerList.size()) re= turn; = String player =3D playerList.get(p= os); - if (player.equals(mpris.getPlayer(= ))) { + if (targetPlayer !=3D null && play= er.equals(targetPlayer.getPlayer())) { return; //Player hasn't actual= ly changed } - mpris.setPlayer(player); - - //Clear values from previous player - ((TextView) findViewById(R.id.now_= playing_textview)).setText(""); - ((TextView) findViewById(R.id.time= _textview)).setText(milisToProgress(0)); - ((SeekBar)findViewById(R.id.positi= onSeek)).setMax(0); + targetPlayer =3D mpris.getPlayerSt= atus(player); + updatePlayerStatus(mpris); } = @Override public void onNothingSelected(AdapterV= iew arg0) { - mpris.setPlayer(null); + targetPlayer =3D null; } }); = if (targetPlayer !=3D null) { - int targetIndex =3D adapter.getPositio= n(targetPlayer); + int targetIndex =3D adapter.getPositio= n(targetPlayer.getPlayer()); if (targetIndex >=3D 0) { spinner.setSelection(targetIndex); - } - targetPlayer =3D null; - } else { - // restore last selected player - int position =3D adapter.getPosition(m= pris.getPlayer()); - if (position >=3D 0) { - spinner.setSelection(position); + } else { + targetPlayer =3D null; } } + updatePlayerStatus(mpris); } }); } @@ -212,7 +163,7 @@ public class MprisActivity extends ActionBarActivity { private final BaseLinkProvider.ConnectionReceiver connectionReceiver = =3D new BaseLinkProvider.ConnectionReceiver() { @Override public void onConnectionReceived(NetworkPackage identityPackage, B= aseLink link) { - connectToPlugin(); + connectToPlugin(null); } = @Override @@ -232,14 +183,59 @@ public class MprisActivity extends ActionBarActivity { }); } = + private void updatePlayerStatus(MprisPlugin mpris) { + MprisPlugin.MprisPlayer playerStatus =3D targetPlayer; + if (playerStatus =3D=3D null) { + //No player with that name found, just display "empty" data + playerStatus =3D mpris.getEmptyPlayer(); + } + String song =3D playerStatus.getCurrentSong(); + + TextView nowPlaying =3D (TextView) findViewById(R.id.now_playing_t= extview); + if (!nowPlaying.getText().toString().equals(song)) { + nowPlaying.setText(song); + } + + if (playerStatus.isSeekAllowed()) { + ((TextView) findViewById(R.id.time_textview)).setText(milisToP= rogress(playerStatus.getLength())); + SeekBar positionSeek =3D (SeekBar)findViewById(R.id.positionSe= ek); + positionSeek.setMax((int)(playerStatus.getLength())); + positionSeek.setProgress((int)(playerStatus.getPosition())); + findViewById(R.id.progress_slider).setVisibility(View.VISIBLE); + } else { + findViewById(R.id.progress_slider).setVisibility(View.GONE); + } + + int volume =3D playerStatus.getVolume(); + ((SeekBar) findViewById(R.id.volume_seek)).setProgress(volume); + + boolean isPlaying =3D playerStatus.isPlaying(); + if (isPlaying) { + ((ImageButton) findViewById(R.id.play_button)).setImageResourc= e(android.R.drawable.ic_media_pause); + findViewById(R.id.play_button).setVisibility(playerStatus.isPa= useAllowed() ? View.VISIBLE : View.GONE); + } else { + ((ImageButton) findViewById(R.id.play_button)).setImageResourc= e(android.R.drawable.ic_media_play); + findViewById(R.id.play_button).setVisibility(playerStatus.isPl= ayAllowed() ? View.VISIBLE : View.GONE); + } + + findViewById(R.id.volume_layout).setVisibility(playerStatus.isSetV= olumeAllowed() ? View.VISIBLE : View.INVISIBLE); + findViewById(R.id.rew_button).setVisibility(playerStatus.isSeekAll= owed() ? View.VISIBLE : View.GONE); + findViewById(R.id.ff_button).setVisibility(playerStatus.isSeekAllo= wed() ? View.VISIBLE : View.GONE); + findViewById(R.id.next_button).setVisibility(playerStatus.isGoNext= Allowed() ? View.VISIBLE : View.GONE); + findViewById(R.id.prev_button).setVisibility(playerStatus.isGoPrev= iousAllowed() ? View.VISIBLE : View.GONE); + } + /** * Change current volume with provided step. * - * @param mpris multimedia controller * @param step step size volume change */ - private void updateVolume(MprisPlugin mpris, int step) { - final int currentVolume =3D mpris.getVolume(); + private void updateVolume(int step) { + if (targetPlayer =3D=3D null) { + return; + } + final int currentVolume =3D targetPlayer.getVolume(); + if(currentVolume < 100 || currentVolume > 0) { int newVolume =3D currentVolume + step; if(newVolume > 100) { @@ -247,7 +243,7 @@ public class MprisActivity extends ActionBarActivity { } else if (newVolume <0 ) { newVolume =3D 0; } - mpris.setVolume(newVolume); + targetPlayer.setVolume(newVolume); } } = @@ -255,26 +251,10 @@ public class MprisActivity extends ActionBarActivity { public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: - BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { - @Override - public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - updateVolume(mpris, 5); - } - }); + updateVolume(5); return true; case KeyEvent.KEYCODE_VOLUME_DOWN: - BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { - @Override - public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - updateVolume(mpris, -5); - } - }); + updateVolume(-5); return true; default: return super.onKeyDown(keyCode, event); @@ -298,7 +278,7 @@ public class MprisActivity extends ActionBarActivity { super.onCreate(savedInstanceState); setContentView(R.layout.mpris_control); = - targetPlayer =3D getIntent().getStringExtra("player"); + final String targetPlayerName =3D getIntent().getStringExtra("play= er"); getIntent().removeExtra("player"); deviceId =3D getIntent().getStringExtra("deviceId"); = @@ -313,7 +293,7 @@ public class MprisActivity extends ActionBarActivity { service.addConnectionListener(connectionReceiver); } }); - connectToPlugin(); + connectToPlugin(targetPlayerName); = findViewById(R.id.play_button).setOnClickListener(new View.OnClick= Listener() { @Override @@ -321,10 +301,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - mpris.sendAction("PlayPause"); + if (targetPlayer =3D=3D null) return; + targetPlayer.playPause(); } }); } @@ -336,10 +314,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - mpris.sendAction("Previous"); + if (targetPlayer =3D=3D null) return; + targetPlayer.previous(); } }); } @@ -351,10 +327,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - mpris.Seek(interval_time * -1); + if (targetPlayer =3D=3D null) return; + targetPlayer.seek(interval_time * -1); } }); } @@ -366,10 +340,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - mpris.Seek(interval_time); + if (targetPlayer =3D=3D null) return; + targetPlayer.seek(interval_time); } }); } @@ -381,10 +353,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - mpris.sendAction("Next"); + if (targetPlayer =3D=3D null) return; + targetPlayer.next(); } }); } @@ -404,10 +374,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris =3D=3D null) return; - mpris.setVolume(seekBar.getProgress()); + if (targetPlayer =3D=3D null) return; + targetPlayer.setVolume(seekBar.getProgress()); } }); } @@ -421,12 +389,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - if (device !=3D null) { - MprisPlugin mpris =3D device.getPlugin(MprisPl= ugin.class); - if (mpris !=3D null) { - positionSeek.setProgress((int) (mpris.getP= osition())); - } + if (targetPlayer !=3D null) { + positionSeek.setProgress((int) (targetPlayer.g= etPosition())); } positionSeekUpdateHandler.removeCallbacks(position= SeekUpdateRunnable); positionSeekUpdateHandler.postDelayed(positionSeek= UpdateRunnable, 1000); @@ -453,10 +417,8 @@ public class MprisActivity extends ActionBarActivity { BackgroundService.RunCommand(MprisActivity.this, new Backg= roundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - Device device =3D service.getDevice(deviceId); - MprisPlugin mpris =3D device.getPlugin(MprisPlugin= .class); - if (mpris !=3D null) { - mpris.setPosition(seekBar.getProgress()); + if (targetPlayer !=3D null) { + targetPlayer.setPosition(seekBar.getProgress()= ); } positionSeekUpdateHandler.postDelayed(positionSeek= UpdateRunnable, 200); } diff --git a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java b/= src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java index 433bc4a..23403a8 100644 --- a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java @@ -33,29 +33,146 @@ import org.kde.kdeconnect.Plugins.Plugin; import org.kde.kdeconnect_tp.R; = import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; = public class MprisPlugin extends Plugin { + public class MprisPlayer { + private String player =3D ""; + private boolean playing =3D false; + private String currentSong =3D ""; + private int volume =3D 50; + private long length =3D -1; + private long lastPosition =3D 0; + private long lastPositionTime; + private boolean playAllowed =3D true; + private boolean pauseAllowed =3D true; + private boolean goNextAllowed =3D true; + private boolean goPreviousAllowed =3D true; + private boolean seekAllowed =3D true; + + public MprisPlayer() { + lastPositionTime =3D System.currentTimeMillis(); + } + + public String getCurrentSong() { + return currentSong; + } + + public String getPlayer() { + return player; + } + + private boolean isSpotify() { + return getPlayer().toLowerCase().equals("spotify"); + } + + public int getVolume() { + return volume; + } + + public long getLength(){ return length; } + + public boolean isPlaying() { + return playing; + } + + public boolean isPlayAllowed() { + return playAllowed; + } + + public boolean isPauseAllowed() { + return pauseAllowed; + } + + public boolean isGoNextAllowed() { + return goNextAllowed; + } + + public boolean isGoPreviousAllowed() { + return goPreviousAllowed; + } + + public boolean isSeekAllowed() { + return seekAllowed && getLength() >=3D 0 && getPosition() >=3D= 0 && !isSpotify(); + } + + public boolean isSetVolumeAllowed() { + return !isSpotify(); + } + + public long getPosition(){ + if(playing) { + return lastPosition + (System.currentTimeMillis() - lastPo= sitionTime); + } else { + return lastPosition; + } + } + + public void playPause() { + if (isPauseAllowed() || isPlayAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "action", "PlayP= ause"); + } + } + + public void play() { + if (isPlayAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "action", "Play"= ); + } + } + + public void pause() { + if (isPauseAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "action", "Pause= "); + } + } + + public void stop() { + MprisPlugin.this.sendCommand(getPlayer(), "action", "Stop"); + } + + public void previous() { + if (isGoPreviousAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "action", "Previ= ous"); + } + } + + public void next() { + if (isGoNextAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "action", "Next"= ); + } + } + + public void setVolume(int volume) { + if (isSetVolumeAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "setVolume", vol= ume); + } + } + + public void setPosition(int position) { + if (isSeekAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "SetPosition", p= osition); + + lastPosition =3D position; + lastPositionTime =3D System.currentTimeMillis(); + } + } + + public void seek(int offset) { + if (isSeekAllowed()) { + MprisPlugin.this.sendCommand(getPlayer(), "Seek", offset); + } + } + } = public final static String PACKAGE_TYPE_MPRIS =3D "kdeconnect.mpris"; public final static String PACKAGE_TYPE_MPRIS_REQUEST =3D "kdeconnect.= mpris.request"; = - private String player =3D ""; - private boolean playing =3D false; - private String currentSong =3D ""; - private int volume =3D 50; - private long length =3D -1; - private long lastPosition; - private long lastPositionTime; - private boolean playAllowed =3D true; - private boolean pauseAllowed =3D true; - private boolean goNextAllowed =3D true; - private boolean goPreviousAllowed =3D true; - private boolean seekAllowed =3D true; + private HashMap players =3D new HashMap<>(); private HashMap playerStatusUpdated =3D new HashMap<>(= ); = - private List playerList =3D new ArrayList<>(); private HashMap playerListUpdated =3D new HashMap<>(); = @Override @@ -81,66 +198,46 @@ public class MprisPlugin extends Plugin { @Override public boolean onCreate() { requestPlayerList(); - lastPositionTime =3D System.currentTimeMillis(); return true; } = @Override public void onDestroy() { - playerList.clear(); - } - - public void sendAction(String player, String action) { - NetworkPackage np =3D new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUES= T); - np.set("player", player); - np.set("action", action); - device.sendPackage(np); - } - public void sendAction(String action) { - sendAction(player, action); + players.clear(); } = - public void setVolume(int volume) { + private void sendCommand(String player, String method, String value) { NetworkPackage np =3D new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUES= T); np.set("player", player); - np.set("setVolume",volume); + np.set(method, value); device.sendPackage(np); } = - public void setPosition(int position) { + private void sendCommand(String player, String method, int value) { NetworkPackage np =3D new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUES= T); np.set("player", player); - np.set("SetPosition", position); - device.sendPackage(np); - this.lastPosition =3D position; - this.lastPositionTime =3D System.currentTimeMillis(); - } - - public void Seek(int offset) { - NetworkPackage np =3D new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUES= T); - np.set("player", player); - np.set("Seek", offset); + np.set(method, value); device.sendPackage(np); } = @Override public boolean onPackageReceived(NetworkPackage np) { - if (np.has("nowPlaying") || np.has("volume") || np.has("isPlaying"= ) || np.has("length") || np.has("pos")) { - if (np.getString("player").equals(player)) { - currentSong =3D np.getString("nowPlaying", currentSong); - volume =3D np.getInt("volume", volume); - length =3D np.getLong("length", length); + MprisPlayer playerStatus =3D players.get(np.getString("player"= )); + if (playerStatus !=3D null) { + playerStatus.currentSong =3D np.getString("nowPlaying", pl= ayerStatus.currentSong); + playerStatus.volume =3D np.getInt("volume", playerStatus.v= olume); + playerStatus.length =3D np.getLong("length", playerStatus.= length); if(np.has("pos")){ - lastPosition =3D np.getLong("pos", lastPosition); - lastPositionTime =3D System.currentTimeMillis(); + playerStatus.lastPosition =3D np.getLong("pos", player= Status.lastPosition); + playerStatus.lastPositionTime =3D System.currentTimeMi= llis(); } - playing =3D np.getBoolean("isPlaying", playing); - playAllowed =3D np.getBoolean("canPlay", playAllowed); - pauseAllowed =3D np.getBoolean("canPause", pauseAllowed); - goNextAllowed =3D np.getBoolean("canGoNext", goNextAllowed= ); - goPreviousAllowed =3D np.getBoolean("canGoPrevious", goPre= viousAllowed); - seekAllowed =3D np.getBoolean("canSeek", seekAllowed); + playerStatus.playing =3D np.getBoolean("isPlaying", player= Status.playing); + playerStatus.playAllowed =3D np.getBoolean("canPlay", play= erStatus.playAllowed); + playerStatus.pauseAllowed =3D np.getBoolean("canPause", pl= ayerStatus.pauseAllowed); + playerStatus.goNextAllowed =3D np.getBoolean("canGoNext", = playerStatus.goNextAllowed); + playerStatus.goPreviousAllowed =3D np.getBoolean("canGoPre= vious", playerStatus.goPreviousAllowed); + playerStatus.seekAllowed =3D np.getBoolean("canSeek", play= erStatus.seekAllowed); for (String key : playerStatusUpdated.keySet()) { try { playerStatusUpdated.get(key).dispatchMessage(new M= essage()); @@ -155,18 +252,37 @@ public class MprisPlugin extends Plugin { = List newPlayerList =3D np.getStringList("playerList"); if (newPlayerList !=3D null) { - boolean equals =3D false; - if (newPlayerList.size() =3D=3D playerList.size()) { - equals =3D true; - for (int i=3D0; i> iter =3D players.= entrySet().iterator(); + while (iter.hasNext()) { + String oldPlayer =3D iter.next().getKey(); + + boolean found =3D false; + for (String newPlayer : newPlayerList) { + if (newPlayer.equals(oldPlayer)) { + found =3D true; break; } } + + if (!found) { + iter.remove(); + equals =3D false; + } } if (!equals) { - playerList =3D newPlayerList; for (String key : playerListUpdated.keySet()) { try { playerListUpdated.get(key).dispatchMessage(new Mes= sage()); @@ -198,8 +314,8 @@ public class MprisPlugin extends Plugin { h.dispatchMessage(new Message()); = //Get the status if this is the first handler we have - if (playerListUpdated.size() =3D=3D 1) { - requestPlayerStatus(); + if (playerListUpdated.size() =3D=3D 1 && !players.isEmpty()) { + requestPlayerStatus(getPlayerList().get(0)); } } = @@ -214,77 +330,18 @@ public class MprisPlugin extends Plugin { } } = - public void setPlayer(String player) { - if (player =3D=3D null || player.equals(this.player)) return; - this.player =3D player; - currentSong =3D ""; - volume =3D 50; - playing =3D false; - playAllowed =3D true; - pauseAllowed =3D true; - goNextAllowed =3D true; - goPreviousAllowed =3D true; - seekAllowed =3D true; - for (String key : playerStatusUpdated.keySet()) { - try { - playerStatusUpdated.get(key).dispatchMessage(new Message()= ); - } catch(Exception e) { - e.printStackTrace(); - Log.e("MprisControl","Exception"); - playerStatusUpdated.remove(key); - } - } - requestPlayerStatus(); - } - public List getPlayerList() { - return playerList; - } - - public String getCurrentSong() { - return currentSong; - } - - public String getPlayer() { - return player; - } - - public int getVolume() { - return volume; - } - - public long getLength(){ return length; } - - public boolean isPlaying() { - return playing; - } - - public boolean isPlayAllowed() { - return playAllowed; - } - - public boolean isPauseAllowed() { - return pauseAllowed; + List playerlist =3D new ArrayList<>(players.keySet()); + Collections.sort(playerlist); + return playerlist; } = - public boolean isGoNextAllowed() { - return goNextAllowed; + public MprisPlayer getPlayerStatus(String player) { + return players.get(player); } = - public boolean isGoPreviousAllowed() { - return goPreviousAllowed; - } - - public boolean isSeekAllowed() { - return seekAllowed; - } - - public long getPosition(){ - if(playing) { - return lastPosition + (System.currentTimeMillis() - lastPositi= onTime); - } else { - return lastPosition; - } + public MprisPlayer getEmptyPlayer() { + return new MprisPlayer(); } = private void requestPlayerList() { @@ -293,9 +350,9 @@ public class MprisPlugin extends Plugin { device.sendPackage(np); } = - private void requestPlayerStatus() { + private void requestPlayerStatus(String player) { NetworkPackage np =3D new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUES= T); - np.set("player",player); + np.set("player", player); np.set("requestNowPlaying",true); np.set("requestVolume",true); device.sendPackage(np);