2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-24 10:58:20 +00:00

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 cases) 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 notification (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
This commit is contained in:
Matthijs Tijink 2017-11-30 23:53:24 +01:00 committed by Aleix Pol
parent 221c6b4fd7
commit cc8330a079
2 changed files with 267 additions and 248 deletions

View File

@ -51,7 +51,7 @@ public class MprisActivity extends ActionBarActivity {
private String deviceId; private String deviceId;
private final Handler positionSeekUpdateHandler = new Handler(); private final Handler positionSeekUpdateHandler = new Handler();
private Runnable positionSeekUpdateRunnable = null; private Runnable positionSeekUpdateRunnable = null;
private String targetPlayer = null; private MprisPlugin.MprisPlayer targetPlayer = null;
private static String milisToProgress(long milis) { private static String milisToProgress(long milis) {
int length = (int)(milis / 1000); //From milis to seconds int length = (int)(milis / 1000); //From milis to seconds
@ -69,7 +69,7 @@ public class MprisActivity extends ActionBarActivity {
text.append(seconds); text.append(seconds);
return text.toString(); return text.toString();
} }
protected void connectToPlugin() { protected void connectToPlugin(final String targetPlayerName) {
BackgroundService.RunCommand(this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(this, new BackgroundService.InstanceCallback() {
@Override @Override
@ -81,6 +81,7 @@ public class MprisActivity extends ActionBarActivity {
Log.e("MprisActivity", "device has no mpris plugin!"); Log.e("MprisActivity", "device has no mpris plugin!");
return; return;
} }
targetPlayer = mpris.getPlayerStatus(targetPlayerName);
mpris.setPlayerStatusUpdatedHandler("activity", new Handler() { mpris.setPlayerStatusUpdatedHandler("activity", new Handler() {
@Override @Override
@ -88,49 +89,7 @@ public class MprisActivity extends ActionBarActivity {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
String song = mpris.getCurrentSong(); updatePlayerStatus(mpris);
TextView nowPlaying = (TextView) findViewById(R.id.now_playing_textview);
if (!nowPlaying.getText().toString().equals(song)) {
nowPlaying.setText(song);
}
//Hacks for Spotify because it reports incorrect info about what it supports
boolean isSpotify = "spotify".equals(mpris.getPlayer().toLowerCase());
if (mpris.getLength() > -1 && mpris.getPosition() > -1 && !isSpotify) {
((TextView) findViewById(R.id.time_textview)).setText(milisToProgress(mpris.getLength()));
SeekBar positionSeek = (SeekBar)findViewById(R.id.positionSeek);
positionSeek.setMax((int)(mpris.getLength()));
positionSeek.setProgress((int)(mpris.getPosition()));
findViewById(R.id.progress_slider).setVisibility(View.VISIBLE);
} else {
findViewById(R.id.progress_slider).setVisibility(View.GONE);
}
int volume = mpris.getVolume();
((SeekBar) findViewById(R.id.volume_seek)).setProgress(volume);
boolean isPlaying = mpris.isPlaying();
if (isPlaying) {
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_pause);
findViewById(R.id.play_button).setVisibility(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).setVisibility(mpris.isPlayAllowed() ? View.VISIBLE : View.GONE);
}
if (isSpotify) {
findViewById(R.id.volume_layout).setVisibility(View.INVISIBLE);
findViewById(R.id.rew_button).setVisibility(View.GONE);
findViewById(R.id.ff_button).setVisibility(View.GONE);
} else {
findViewById(R.id.volume_layout).setVisibility(View.VISIBLE);
findViewById(R.id.rew_button).setVisibility(mpris.isSeekAllowed() ? View.VISIBLE : View.GONE);
findViewById(R.id.ff_button).setVisibility(mpris.isSeekAllowed() ? View.VISIBLE : View.GONE);
}
findViewById(R.id.next_button).setVisibility(mpris.isGoNextAllowed() ? View.VISIBLE : View.GONE);
findViewById(R.id.prev_button).setVisibility(mpris.isGoPreviousAllowed() ? View.VISIBLE : View.GONE);
} }
}); });
} }
@ -169,36 +128,28 @@ public class MprisActivity extends ActionBarActivity {
if (pos >= playerList.size()) return; if (pos >= playerList.size()) return;
String player = playerList.get(pos); String player = playerList.get(pos);
if (player.equals(mpris.getPlayer())) { if (targetPlayer != null && player.equals(targetPlayer.getPlayer())) {
return; //Player hasn't actually changed return; //Player hasn't actually changed
} }
mpris.setPlayer(player); targetPlayer = mpris.getPlayerStatus(player);
updatePlayerStatus(mpris);
//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.positionSeek)).setMax(0);
} }
@Override @Override
public void onNothingSelected(AdapterView<?> arg0) { public void onNothingSelected(AdapterView<?> arg0) {
mpris.setPlayer(null); targetPlayer = null;
} }
}); });
if (targetPlayer != null) { if (targetPlayer != null) {
int targetIndex = adapter.getPosition(targetPlayer); int targetIndex = adapter.getPosition(targetPlayer.getPlayer());
if (targetIndex >= 0) { if (targetIndex >= 0) {
spinner.setSelection(targetIndex); spinner.setSelection(targetIndex);
}
targetPlayer = null;
} else { } else {
// restore last selected player targetPlayer = null;
int position = adapter.getPosition(mpris.getPlayer());
if (position >= 0) {
spinner.setSelection(position);
} }
} }
updatePlayerStatus(mpris);
} }
}); });
} }
@ -212,7 +163,7 @@ public class MprisActivity extends ActionBarActivity {
private final BaseLinkProvider.ConnectionReceiver connectionReceiver = new BaseLinkProvider.ConnectionReceiver() { private final BaseLinkProvider.ConnectionReceiver connectionReceiver = new BaseLinkProvider.ConnectionReceiver() {
@Override @Override
public void onConnectionReceived(NetworkPackage identityPackage, BaseLink link) { public void onConnectionReceived(NetworkPackage identityPackage, BaseLink link) {
connectToPlugin(); connectToPlugin(null);
} }
@Override @Override
@ -232,14 +183,59 @@ public class MprisActivity extends ActionBarActivity {
}); });
} }
private void updatePlayerStatus(MprisPlugin mpris) {
MprisPlugin.MprisPlayer playerStatus = targetPlayer;
if (playerStatus == null) {
//No player with that name found, just display "empty" data
playerStatus = mpris.getEmptyPlayer();
}
String song = playerStatus.getCurrentSong();
TextView nowPlaying = (TextView) findViewById(R.id.now_playing_textview);
if (!nowPlaying.getText().toString().equals(song)) {
nowPlaying.setText(song);
}
if (playerStatus.isSeekAllowed()) {
((TextView) findViewById(R.id.time_textview)).setText(milisToProgress(playerStatus.getLength()));
SeekBar positionSeek = (SeekBar)findViewById(R.id.positionSeek);
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 = playerStatus.getVolume();
((SeekBar) findViewById(R.id.volume_seek)).setProgress(volume);
boolean isPlaying = playerStatus.isPlaying();
if (isPlaying) {
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_pause);
findViewById(R.id.play_button).setVisibility(playerStatus.isPauseAllowed() ? View.VISIBLE : View.GONE);
} else {
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_play);
findViewById(R.id.play_button).setVisibility(playerStatus.isPlayAllowed() ? View.VISIBLE : View.GONE);
}
findViewById(R.id.volume_layout).setVisibility(playerStatus.isSetVolumeAllowed() ? View.VISIBLE : View.INVISIBLE);
findViewById(R.id.rew_button).setVisibility(playerStatus.isSeekAllowed() ? View.VISIBLE : View.GONE);
findViewById(R.id.ff_button).setVisibility(playerStatus.isSeekAllowed() ? View.VISIBLE : View.GONE);
findViewById(R.id.next_button).setVisibility(playerStatus.isGoNextAllowed() ? View.VISIBLE : View.GONE);
findViewById(R.id.prev_button).setVisibility(playerStatus.isGoPreviousAllowed() ? View.VISIBLE : View.GONE);
}
/** /**
* Change current volume with provided step. * Change current volume with provided step.
* *
* @param mpris multimedia controller
* @param step step size volume change * @param step step size volume change
*/ */
private void updateVolume(MprisPlugin mpris, int step) { private void updateVolume(int step) {
final int currentVolume = mpris.getVolume(); if (targetPlayer == null) {
return;
}
final int currentVolume = targetPlayer.getVolume();
if(currentVolume < 100 || currentVolume > 0) { if(currentVolume < 100 || currentVolume > 0) {
int newVolume = currentVolume + step; int newVolume = currentVolume + step;
if(newVolume > 100) { if(newVolume > 100) {
@ -247,7 +243,7 @@ public class MprisActivity extends ActionBarActivity {
} else if (newVolume <0 ) { } else if (newVolume <0 ) {
newVolume = 0; newVolume = 0;
} }
mpris.setVolume(newVolume); targetPlayer.setVolume(newVolume);
} }
} }
@ -255,26 +251,10 @@ public class MprisActivity extends ActionBarActivity {
public boolean onKeyDown(int keyCode, KeyEvent event) { public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) { switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_UP:
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { updateVolume(5);
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId);
MprisPlugin mpris = device.getPlugin(MprisPlugin.class);
if (mpris == null) return;
updateVolume(mpris, 5);
}
});
return true; return true;
case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_DOWN:
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { updateVolume(-5);
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId);
MprisPlugin mpris = device.getPlugin(MprisPlugin.class);
if (mpris == null) return;
updateVolume(mpris, -5);
}
});
return true; return true;
default: default:
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
@ -298,7 +278,7 @@ public class MprisActivity extends ActionBarActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.mpris_control); setContentView(R.layout.mpris_control);
targetPlayer = getIntent().getStringExtra("player"); final String targetPlayerName = getIntent().getStringExtra("player");
getIntent().removeExtra("player"); getIntent().removeExtra("player");
deviceId = getIntent().getStringExtra("deviceId"); deviceId = getIntent().getStringExtra("deviceId");
@ -313,7 +293,7 @@ public class MprisActivity extends ActionBarActivity {
service.addConnectionListener(connectionReceiver); service.addConnectionListener(connectionReceiver);
} }
}); });
connectToPlugin(); connectToPlugin(targetPlayerName);
findViewById(R.id.play_button).setOnClickListener(new View.OnClickListener() { findViewById(R.id.play_button).setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -321,10 +301,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer == null) return;
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.playPause();
if (mpris == null) return;
mpris.sendAction("PlayPause");
} }
}); });
} }
@ -336,10 +314,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer == null) return;
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.previous();
if (mpris == null) return;
mpris.sendAction("Previous");
} }
}); });
} }
@ -351,10 +327,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer == null) return;
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.seek(interval_time * -1);
if (mpris == null) return;
mpris.Seek(interval_time * -1);
} }
}); });
} }
@ -366,10 +340,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer == null) return;
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.seek(interval_time);
if (mpris == null) return;
mpris.Seek(interval_time);
} }
}); });
} }
@ -381,10 +353,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer == null) return;
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.next();
if (mpris == null) return;
mpris.sendAction("Next");
} }
}); });
} }
@ -404,10 +374,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer == null) return;
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.setVolume(seekBar.getProgress());
if (mpris == null) return;
mpris.setVolume(seekBar.getProgress());
} }
}); });
} }
@ -421,12 +389,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer != null) {
if (device != null) { positionSeek.setProgress((int) (targetPlayer.getPosition()));
MprisPlugin mpris = device.getPlugin(MprisPlugin.class);
if (mpris != null) {
positionSeek.setProgress((int) (mpris.getPosition()));
}
} }
positionSeekUpdateHandler.removeCallbacks(positionSeekUpdateRunnable); positionSeekUpdateHandler.removeCallbacks(positionSeekUpdateRunnable);
positionSeekUpdateHandler.postDelayed(positionSeekUpdateRunnable, 1000); positionSeekUpdateHandler.postDelayed(positionSeekUpdateRunnable, 1000);
@ -453,10 +417,8 @@ public class MprisActivity extends ActionBarActivity {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() { BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override @Override
public void onServiceStart(BackgroundService service) { public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId); if (targetPlayer != null) {
MprisPlugin mpris = device.getPlugin(MprisPlugin.class); targetPlayer.setPosition(seekBar.getProgress());
if (mpris != null) {
mpris.setPosition(seekBar.getProgress());
} }
positionSeekUpdateHandler.postDelayed(positionSeekUpdateRunnable, 200); positionSeekUpdateHandler.postDelayed(positionSeekUpdateRunnable, 200);
} }

View File

@ -33,29 +33,146 @@ import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
public class MprisPlugin extends Plugin { public class MprisPlugin extends Plugin {
public class MprisPlayer {
public final static String PACKAGE_TYPE_MPRIS = "kdeconnect.mpris";
public final static String PACKAGE_TYPE_MPRIS_REQUEST = "kdeconnect.mpris.request";
private String player = ""; private String player = "";
private boolean playing = false; private boolean playing = false;
private String currentSong = ""; private String currentSong = "";
private int volume = 50; private int volume = 50;
private long length = -1; private long length = -1;
private long lastPosition; private long lastPosition = 0;
private long lastPositionTime; private long lastPositionTime;
private boolean playAllowed = true; private boolean playAllowed = true;
private boolean pauseAllowed = true; private boolean pauseAllowed = true;
private boolean goNextAllowed = true; private boolean goNextAllowed = true;
private boolean goPreviousAllowed = true; private boolean goPreviousAllowed = true;
private boolean seekAllowed = true; private boolean seekAllowed = true;
public MprisPlayer() {
lastPositionTime = 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() >= 0 && getPosition() >= 0 && !isSpotify();
}
public boolean isSetVolumeAllowed() {
return !isSpotify();
}
public long getPosition(){
if(playing) {
return lastPosition + (System.currentTimeMillis() - lastPositionTime);
} else {
return lastPosition;
}
}
public void playPause() {
if (isPauseAllowed() || isPlayAllowed()) {
MprisPlugin.this.sendCommand(getPlayer(), "action", "PlayPause");
}
}
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", "Previous");
}
}
public void next() {
if (isGoNextAllowed()) {
MprisPlugin.this.sendCommand(getPlayer(), "action", "Next");
}
}
public void setVolume(int volume) {
if (isSetVolumeAllowed()) {
MprisPlugin.this.sendCommand(getPlayer(), "setVolume", volume);
}
}
public void setPosition(int position) {
if (isSeekAllowed()) {
MprisPlugin.this.sendCommand(getPlayer(), "SetPosition", position);
lastPosition = position;
lastPositionTime = System.currentTimeMillis();
}
}
public void seek(int offset) {
if (isSeekAllowed()) {
MprisPlugin.this.sendCommand(getPlayer(), "Seek", offset);
}
}
}
public final static String PACKAGE_TYPE_MPRIS = "kdeconnect.mpris";
public final static String PACKAGE_TYPE_MPRIS_REQUEST = "kdeconnect.mpris.request";
private HashMap<String, MprisPlayer> players = new HashMap<>();
private HashMap<String,Handler> playerStatusUpdated = new HashMap<>(); private HashMap<String,Handler> playerStatusUpdated = new HashMap<>();
private List<String> playerList = new ArrayList<>();
private HashMap<String,Handler> playerListUpdated = new HashMap<>(); private HashMap<String,Handler> playerListUpdated = new HashMap<>();
@Override @Override
@ -81,66 +198,46 @@ public class MprisPlugin extends Plugin {
@Override @Override
public boolean onCreate() { public boolean onCreate() {
requestPlayerList(); requestPlayerList();
lastPositionTime = System.currentTimeMillis();
return true; return true;
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
playerList.clear(); players.clear();
} }
public void sendAction(String player, String action) { private void sendCommand(String player, String method, String value) {
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST); NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST);
np.set("player", player); np.set("player", player);
np.set("action", action); np.set(method, value);
device.sendPackage(np);
}
public void sendAction(String action) {
sendAction(player, action);
}
public void setVolume(int volume) {
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST);
np.set("player", player);
np.set("setVolume",volume);
device.sendPackage(np); device.sendPackage(np);
} }
public void setPosition(int position) { private void sendCommand(String player, String method, int value) {
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST); NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST);
np.set("player", player); np.set("player", player);
np.set("SetPosition", position); np.set(method, value);
device.sendPackage(np);
this.lastPosition = position;
this.lastPositionTime = System.currentTimeMillis();
}
public void Seek(int offset) {
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST);
np.set("player", player);
np.set("Seek", offset);
device.sendPackage(np); device.sendPackage(np);
} }
@Override @Override
public boolean onPackageReceived(NetworkPackage np) { public boolean onPackageReceived(NetworkPackage np) {
if (np.has("nowPlaying") || np.has("volume") || np.has("isPlaying") || np.has("length") || np.has("pos")) { if (np.has("nowPlaying") || np.has("volume") || np.has("isPlaying") || np.has("length") || np.has("pos")) {
if (np.getString("player").equals(player)) { MprisPlayer playerStatus = players.get(np.getString("player"));
currentSong = np.getString("nowPlaying", currentSong); if (playerStatus != null) {
volume = np.getInt("volume", volume); playerStatus.currentSong = np.getString("nowPlaying", playerStatus.currentSong);
length = np.getLong("length", length); playerStatus.volume = np.getInt("volume", playerStatus.volume);
playerStatus.length = np.getLong("length", playerStatus.length);
if(np.has("pos")){ if(np.has("pos")){
lastPosition = np.getLong("pos", lastPosition); playerStatus.lastPosition = np.getLong("pos", playerStatus.lastPosition);
lastPositionTime = System.currentTimeMillis(); playerStatus.lastPositionTime = System.currentTimeMillis();
} }
playing = np.getBoolean("isPlaying", playing); playerStatus.playing = np.getBoolean("isPlaying", playerStatus.playing);
playAllowed = np.getBoolean("canPlay", playAllowed); playerStatus.playAllowed = np.getBoolean("canPlay", playerStatus.playAllowed);
pauseAllowed = np.getBoolean("canPause", pauseAllowed); playerStatus.pauseAllowed = np.getBoolean("canPause", playerStatus.pauseAllowed);
goNextAllowed = np.getBoolean("canGoNext", goNextAllowed); playerStatus.goNextAllowed = np.getBoolean("canGoNext", playerStatus.goNextAllowed);
goPreviousAllowed = np.getBoolean("canGoPrevious", goPreviousAllowed); playerStatus.goPreviousAllowed = np.getBoolean("canGoPrevious", playerStatus.goPreviousAllowed);
seekAllowed = np.getBoolean("canSeek", seekAllowed); playerStatus.seekAllowed = np.getBoolean("canSeek", playerStatus.seekAllowed);
for (String key : playerStatusUpdated.keySet()) { for (String key : playerStatusUpdated.keySet()) {
try { try {
playerStatusUpdated.get(key).dispatchMessage(new Message()); playerStatusUpdated.get(key).dispatchMessage(new Message());
@ -155,18 +252,37 @@ public class MprisPlugin extends Plugin {
List<String> newPlayerList = np.getStringList("playerList"); List<String> newPlayerList = np.getStringList("playerList");
if (newPlayerList != null) { if (newPlayerList != null) {
boolean equals = false; boolean equals = true;
if (newPlayerList.size() == playerList.size()) { for (String newPlayer : newPlayerList) {
equals = true; if (!players.containsKey(newPlayer)) {
for (int i=0; i<newPlayerList.size(); i++) {
if (!newPlayerList.get(i).equals(playerList.get(i))) {
equals = false; equals = false;
MprisPlayer player = new MprisPlayer();
player.player = newPlayer;
players.put(newPlayer, player);
//Immediately ask for the data of this player
requestPlayerStatus(newPlayer);
}
}
Iterator<HashMap.Entry<String, MprisPlayer>> iter = players.entrySet().iterator();
while (iter.hasNext()) {
String oldPlayer = iter.next().getKey();
boolean found = false;
for (String newPlayer : newPlayerList) {
if (newPlayer.equals(oldPlayer)) {
found = true;
break; break;
} }
} }
if (!found) {
iter.remove();
equals = false;
}
} }
if (!equals) { if (!equals) {
playerList = newPlayerList;
for (String key : playerListUpdated.keySet()) { for (String key : playerListUpdated.keySet()) {
try { try {
playerListUpdated.get(key).dispatchMessage(new Message()); playerListUpdated.get(key).dispatchMessage(new Message());
@ -198,8 +314,8 @@ public class MprisPlugin extends Plugin {
h.dispatchMessage(new Message()); h.dispatchMessage(new Message());
//Get the status if this is the first handler we have //Get the status if this is the first handler we have
if (playerListUpdated.size() == 1) { if (playerListUpdated.size() == 1 && !players.isEmpty()) {
requestPlayerStatus(); requestPlayerStatus(getPlayerList().get(0));
} }
} }
@ -214,77 +330,18 @@ public class MprisPlugin extends Plugin {
} }
} }
public void setPlayer(String player) {
if (player == null || player.equals(this.player)) return;
this.player = player;
currentSong = "";
volume = 50;
playing = false;
playAllowed = true;
pauseAllowed = true;
goNextAllowed = true;
goPreviousAllowed = true;
seekAllowed = 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<String> getPlayerList() { public List<String> getPlayerList() {
return playerList; List<String> playerlist = new ArrayList<>(players.keySet());
Collections.sort(playerlist);
return playerlist;
} }
public String getCurrentSong() { public MprisPlayer getPlayerStatus(String player) {
return currentSong; return players.get(player);
} }
public String getPlayer() { public MprisPlayer getEmptyPlayer() {
return player; return new MprisPlayer();
}
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;
}
public long getPosition(){
if(playing) {
return lastPosition + (System.currentTimeMillis() - lastPositionTime);
} else {
return lastPosition;
}
} }
private void requestPlayerList() { private void requestPlayerList() {
@ -293,9 +350,9 @@ public class MprisPlugin extends Plugin {
device.sendPackage(np); device.sendPackage(np);
} }
private void requestPlayerStatus() { private void requestPlayerStatus(String player) {
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST); NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_MPRIS_REQUEST);
np.set("player",player); np.set("player", player);
np.set("requestNowPlaying",true); np.set("requestNowPlaying",true);
np.set("requestVolume",true); np.set("requestVolume",true);
device.sendPackage(np); device.sendPackage(np);