Fixed issue with registering observers multiple times (#605)
Registering observers would cause the runnables to be posted multiple times to the checkerHandler. This resulted in callbacks being called more than once when a result was received.
This commit is contained in:
parent
0c68ad1610
commit
e60df7e8ac
|
@ -23,8 +23,8 @@ import org.xbmc.kore.jsonrpc.HostConnection;
|
||||||
import org.xbmc.kore.jsonrpc.method.JSONRPC;
|
import org.xbmc.kore.jsonrpc.method.JSONRPC;
|
||||||
import org.xbmc.kore.jsonrpc.method.Player;
|
import org.xbmc.kore.jsonrpc.method.Player;
|
||||||
import org.xbmc.kore.jsonrpc.notification.Application;
|
import org.xbmc.kore.jsonrpc.notification.Application;
|
||||||
import org.xbmc.kore.jsonrpc.notification.Player.NotificationsData;
|
|
||||||
import org.xbmc.kore.jsonrpc.notification.Input;
|
import org.xbmc.kore.jsonrpc.notification.Input;
|
||||||
|
import org.xbmc.kore.jsonrpc.notification.Player.NotificationsData;
|
||||||
import org.xbmc.kore.jsonrpc.notification.System;
|
import org.xbmc.kore.jsonrpc.notification.System;
|
||||||
import org.xbmc.kore.jsonrpc.type.ApplicationType;
|
import org.xbmc.kore.jsonrpc.type.ApplicationType;
|
||||||
import org.xbmc.kore.jsonrpc.type.ListType;
|
import org.xbmc.kore.jsonrpc.type.ListType;
|
||||||
|
@ -52,6 +52,9 @@ public class HostConnectionObserver
|
||||||
HostConnection.ApplicationNotificationsObserver {
|
HostConnection.ApplicationNotificationsObserver {
|
||||||
public static final String TAG = LogUtils.makeLogTag(HostConnectionObserver.class);
|
public static final String TAG = LogUtils.makeLogTag(HostConnectionObserver.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface that an observer has to implement to receive playlist events
|
||||||
|
*/
|
||||||
public interface ApplicationEventsObserver {
|
public interface ApplicationEventsObserver {
|
||||||
/**
|
/**
|
||||||
* Notifies the observer that volume has changed
|
* Notifies the observer that volume has changed
|
||||||
|
@ -148,55 +151,57 @@ public class HostConnectionObserver
|
||||||
|
|
||||||
// Associate the Handler with the UI thread
|
// Associate the Handler with the UI thread
|
||||||
private Handler checkerHandler = new Handler(Looper.getMainLooper());
|
private Handler checkerHandler = new Handler(Looper.getMainLooper());
|
||||||
private Runnable httpPlayerCheckerRunnable = new Runnable() {
|
private Runnable httpCheckerRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final int HTTP_NOTIFICATION_CHECK_INTERVAL = 3000;
|
final int HTTP_NOTIFICATION_CHECK_INTERVAL = 3000;
|
||||||
// If no one is listening to this, just exit
|
boolean keepChecking = false;
|
||||||
if (playerEventsObservers.isEmpty()) return;
|
if ( ! playerEventsObservers.isEmpty() ) {
|
||||||
|
keepChecking = true;
|
||||||
|
checkWhatsPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
// Check whats playing
|
if ( ! applicationEventsObservers.isEmpty() ) {
|
||||||
checkWhatsPlaying();
|
keepChecking = true;
|
||||||
|
getApplicationProperties();
|
||||||
|
}
|
||||||
|
|
||||||
// Keep checking
|
if (keepChecking)
|
||||||
checkerHandler.postDelayed(this, HTTP_NOTIFICATION_CHECK_INTERVAL);
|
checkerHandler.postDelayed(this, HTTP_NOTIFICATION_CHECK_INTERVAL);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private Runnable httpApplicationCheckerRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
final int HTTP_NOTIFICATION_CHECK_INTERVAL = 3000;
|
|
||||||
// If no one is listening to this, just exit
|
|
||||||
if (applicationEventsObservers.isEmpty()) return;
|
|
||||||
|
|
||||||
getApplicationProperties();
|
|
||||||
|
|
||||||
// Keep checking
|
|
||||||
checkerHandler.postDelayed(this, HTTP_NOTIFICATION_CHECK_INTERVAL);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private Runnable tcpCheckerRunnable = new Runnable() {
|
private Runnable tcpCheckerRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// If no one is listening to this, just exit
|
||||||
|
if (playerEventsObservers.isEmpty() && applicationEventsObservers.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
final int PING_AFTER_ERROR_CHECK_INTERVAL = 2000,
|
final int PING_AFTER_ERROR_CHECK_INTERVAL = 2000,
|
||||||
PING_AFTER_SUCCESS_CHECK_INTERVAL = 10000;
|
PING_AFTER_SUCCESS_CHECK_INTERVAL = 10000;
|
||||||
// If no one is listening to this, just exit
|
|
||||||
if (playerEventsObservers.isEmpty() && applicationEventsObservers.isEmpty()) return;
|
|
||||||
|
|
||||||
JSONRPC.Ping ping = new JSONRPC.Ping();
|
JSONRPC.Ping ping = new JSONRPC.Ping();
|
||||||
ping.execute(connection, new ApiCallback<String>() {
|
ping.execute(connection, new ApiCallback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(String result) {
|
public void onSuccess(String result) {
|
||||||
|
boolean keepChecking = false;
|
||||||
|
|
||||||
// Ok, we've got a ping, if there are playerEventsObservers and
|
// Ok, we've got a ping, if there are playerEventsObservers and
|
||||||
// we were in a error or uninitialized state, update
|
// we were in a error or uninitialized state, update
|
||||||
if ((! playerEventsObservers.isEmpty()) &&
|
if ((! playerEventsObservers.isEmpty()) &&
|
||||||
((hostState.lastCallResult == PlayerEventsObserver.PLAYER_NO_RESULT) ||
|
((hostState.lastCallResult == PlayerEventsObserver.PLAYER_NO_RESULT) ||
|
||||||
(hostState.lastCallResult == PlayerEventsObserver.PLAYER_CONNECTION_ERROR))) {
|
(hostState.lastCallResult == PlayerEventsObserver.PLAYER_CONNECTION_ERROR))) {
|
||||||
checkWhatsPlaying();
|
checkWhatsPlaying();
|
||||||
|
keepChecking = true;
|
||||||
}
|
}
|
||||||
checkerHandler.postDelayed(tcpCheckerRunnable, PING_AFTER_SUCCESS_CHECK_INTERVAL);
|
|
||||||
|
if ( ! applicationEventsObservers.isEmpty() ) {
|
||||||
|
getApplicationProperties();
|
||||||
|
keepChecking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keepChecking)
|
||||||
|
checkerHandler.postDelayed(tcpCheckerRunnable, PING_AFTER_SUCCESS_CHECK_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -206,12 +211,6 @@ public class HostConnectionObserver
|
||||||
checkerHandler.postDelayed(tcpCheckerRunnable, PING_AFTER_ERROR_CHECK_INTERVAL);
|
checkerHandler.postDelayed(tcpCheckerRunnable, PING_AFTER_ERROR_CHECK_INTERVAL);
|
||||||
}
|
}
|
||||||
}, checkerHandler);
|
}, checkerHandler);
|
||||||
// if ((lastCallResult == PlayerEventsObserver.PLAYER_NO_RESULT) ||
|
|
||||||
// (lastCallResult == PlayerEventsObserver.PLAYER_CONNECTION_ERROR)) {
|
|
||||||
// checkerHandler.postDelayed(tcpCheckerRunnable, PING_AFTER_ERROR_CHECK_INTERVAL);
|
|
||||||
// } else {
|
|
||||||
// checkerHandler.postDelayed(tcpCheckerRunnable, PING_AFTER_SUCCESS_CHECK_INTERVAL);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -251,7 +250,8 @@ public class HostConnectionObserver
|
||||||
if (this.connection == null)
|
if (this.connection == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
playerEventsObservers.add(observer);
|
if ( ! playerEventsObservers.contains(observer) )
|
||||||
|
playerEventsObservers.add(observer);
|
||||||
|
|
||||||
if (replyImmediately) replyWithLastResult(observer);
|
if (replyImmediately) replyWithLastResult(observer);
|
||||||
|
|
||||||
|
@ -262,12 +262,10 @@ public class HostConnectionObserver
|
||||||
connection.registerPlayerNotificationsObserver(this, checkerHandler);
|
connection.registerPlayerNotificationsObserver(this, checkerHandler);
|
||||||
connection.registerSystemNotificationsObserver(this, checkerHandler);
|
connection.registerSystemNotificationsObserver(this, checkerHandler);
|
||||||
connection.registerInputNotificationsObserver(this, checkerHandler);
|
connection.registerInputNotificationsObserver(this, checkerHandler);
|
||||||
// Start the ping checker
|
|
||||||
checkerHandler.post(tcpCheckerRunnable);
|
|
||||||
} else {
|
|
||||||
checkerHandler.post(httpPlayerCheckerRunnable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startCheckerHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,9 +287,6 @@ public class HostConnectionObserver
|
||||||
connection.unregisterPlayerNotificationsObserver(this);
|
connection.unregisterPlayerNotificationsObserver(this);
|
||||||
connection.unregisterSystemNotificationsObserver(this);
|
connection.unregisterSystemNotificationsObserver(this);
|
||||||
connection.unregisterInputNotificationsObserver(this);
|
connection.unregisterInputNotificationsObserver(this);
|
||||||
checkerHandler.removeCallbacks(tcpCheckerRunnable);
|
|
||||||
} else {
|
|
||||||
checkerHandler.removeCallbacks(httpPlayerCheckerRunnable);
|
|
||||||
}
|
}
|
||||||
hostState.lastCallResult = PlayerEventsObserver.PLAYER_NO_RESULT;
|
hostState.lastCallResult = PlayerEventsObserver.PLAYER_NO_RESULT;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +301,8 @@ public class HostConnectionObserver
|
||||||
if (this.connection == null)
|
if (this.connection == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
applicationEventsObservers.add(observer);
|
if (! applicationEventsObservers.contains(observer) )
|
||||||
|
applicationEventsObservers.add(observer);
|
||||||
|
|
||||||
if (replyImmediately) {
|
if (replyImmediately) {
|
||||||
if( hostState.volumeLevel == -1 ) {
|
if( hostState.volumeLevel == -1 ) {
|
||||||
|
@ -321,11 +317,10 @@ public class HostConnectionObserver
|
||||||
// as a connection observer, which we will pass to the "real" observer
|
// as a connection observer, which we will pass to the "real" observer
|
||||||
if (connection.getProtocol() == HostConnection.PROTOCOL_TCP) {
|
if (connection.getProtocol() == HostConnection.PROTOCOL_TCP) {
|
||||||
connection.registerApplicationNotificationsObserver(this, checkerHandler);
|
connection.registerApplicationNotificationsObserver(this, checkerHandler);
|
||||||
checkerHandler.post(tcpCheckerRunnable);
|
|
||||||
} else {
|
|
||||||
checkerHandler.post(httpApplicationCheckerRunnable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startCheckerHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -344,8 +339,6 @@ public class HostConnectionObserver
|
||||||
// the http checker thread
|
// the http checker thread
|
||||||
if (connection.getProtocol() == HostConnection.PROTOCOL_TCP) {
|
if (connection.getProtocol() == HostConnection.PROTOCOL_TCP) {
|
||||||
connection.unregisterApplicationNotificationsObserver(this);
|
connection.unregisterApplicationNotificationsObserver(this);
|
||||||
} else {
|
|
||||||
checkerHandler.removeCallbacks(httpApplicationCheckerRunnable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,9 +356,8 @@ public class HostConnectionObserver
|
||||||
connection.unregisterPlayerNotificationsObserver(this);
|
connection.unregisterPlayerNotificationsObserver(this);
|
||||||
connection.unregisterSystemNotificationsObserver(this);
|
connection.unregisterSystemNotificationsObserver(this);
|
||||||
connection.unregisterInputNotificationsObserver(this);
|
connection.unregisterInputNotificationsObserver(this);
|
||||||
|
connection.unregisterApplicationNotificationsObserver(this);
|
||||||
checkerHandler.removeCallbacks(tcpCheckerRunnable);
|
checkerHandler.removeCallbacks(tcpCheckerRunnable);
|
||||||
} else {
|
|
||||||
checkerHandler.removeCallbacks(httpPlayerCheckerRunnable);
|
|
||||||
}
|
}
|
||||||
hostState.lastCallResult = PlayerEventsObserver.PLAYER_NO_RESULT;
|
hostState.lastCallResult = PlayerEventsObserver.PLAYER_NO_RESULT;
|
||||||
}
|
}
|
||||||
|
@ -456,6 +448,18 @@ public class HostConnectionObserver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startCheckerHandler() {
|
||||||
|
// Check if checkerHandler is already running, to prevent multiple runnables to be posted
|
||||||
|
// when multiple observers are registered.
|
||||||
|
if ( checkerHandler.hasMessages(0) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (connection.getProtocol() == HostConnection.PROTOCOL_TCP) {
|
||||||
|
checkerHandler.post(tcpCheckerRunnable);
|
||||||
|
} else {
|
||||||
|
checkerHandler.post(httpCheckerRunnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
private void getApplicationProperties() {
|
private void getApplicationProperties() {
|
||||||
org.xbmc.kore.jsonrpc.method.Application.GetProperties getProperties =
|
org.xbmc.kore.jsonrpc.method.Application.GetProperties getProperties =
|
||||||
new org.xbmc.kore.jsonrpc.method.Application.GetProperties(org.xbmc.kore.jsonrpc.method.Application.GetProperties.VOLUME,
|
new org.xbmc.kore.jsonrpc.method.Application.GetProperties(org.xbmc.kore.jsonrpc.method.Application.GetProperties.VOLUME,
|
||||||
|
|
Loading…
Reference in New Issue