use sets instead of list for listeners
This commit is contained in:
parent
3782a6fac6
commit
a23d9929f1
|
@ -57,6 +57,7 @@ import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
@ -259,14 +260,16 @@ public class XmppConnectionService extends Service {
|
||||||
private int unreadCount = -1;
|
private int unreadCount = -1;
|
||||||
|
|
||||||
//Ui callback listeners
|
//Ui callback listeners
|
||||||
private final List<OnConversationUpdate> mOnConversationUpdates = new ArrayList<>();
|
private final Set<OnConversationUpdate> mOnConversationUpdates = Collections.newSetFromMap(new WeakHashMap<OnConversationUpdate, Boolean>());
|
||||||
private final List<OnShowErrorToast> mOnShowErrorToasts = new ArrayList<>();
|
private final Set<OnShowErrorToast> mOnShowErrorToasts = Collections.newSetFromMap(new WeakHashMap<OnShowErrorToast, Boolean>());
|
||||||
private final List<OnAccountUpdate> mOnAccountUpdates = new ArrayList<>();
|
private final Set<OnAccountUpdate> mOnAccountUpdates = Collections.newSetFromMap(new WeakHashMap<OnAccountUpdate, Boolean>());
|
||||||
private final List<OnCaptchaRequested> mOnCaptchaRequested = new ArrayList<>();
|
private final Set<OnCaptchaRequested> mOnCaptchaRequested = Collections.newSetFromMap(new WeakHashMap<OnCaptchaRequested, Boolean>());
|
||||||
private final List<OnRosterUpdate> mOnRosterUpdates = new ArrayList<>();
|
private final Set<OnRosterUpdate> mOnRosterUpdates = Collections.newSetFromMap(new WeakHashMap<OnRosterUpdate, Boolean>());
|
||||||
private final List<OnUpdateBlocklist> mOnUpdateBlocklist = new ArrayList<>();
|
private final Set<OnUpdateBlocklist> mOnUpdateBlocklist = Collections.newSetFromMap(new WeakHashMap<OnUpdateBlocklist, Boolean>());
|
||||||
private final List<OnMucRosterUpdate> mOnMucRosterUpdate = new ArrayList<>();
|
private final Set<OnMucRosterUpdate> mOnMucRosterUpdate = Collections.newSetFromMap(new WeakHashMap<OnMucRosterUpdate, Boolean>());
|
||||||
private final List<OnKeyStatusUpdated> mOnKeyStatusUpdated = new ArrayList<>();
|
private final Set<OnKeyStatusUpdated> mOnKeyStatusUpdated = Collections.newSetFromMap(new WeakHashMap<OnKeyStatusUpdated, Boolean>());
|
||||||
|
|
||||||
|
private final Object LISTENER_LOCK = new Object();
|
||||||
|
|
||||||
|
|
||||||
private final OnBindListener mOnBindListener = new OnBindListener() {
|
private final OnBindListener mOnBindListener = new OnBindListener() {
|
||||||
|
@ -1889,17 +1892,19 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnConversationListChangedListener(OnConversationUpdate listener) {
|
public void setOnConversationListChangedListener(OnConversationUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnConversationUpdates.add(listener);
|
if (!this.mOnConversationUpdates.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as ConversationListChangedListener");
|
||||||
|
}
|
||||||
this.mNotificationService.setIsInForeground(this.mOnConversationUpdates.size() > 0);
|
this.mNotificationService.setIsInForeground(this.mOnConversationUpdates.size() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnConversationListChangedListener(OnConversationUpdate listener) {
|
public void removeOnConversationListChangedListener(OnConversationUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnConversationUpdates.remove(listener);
|
this.mOnConversationUpdates.remove(listener);
|
||||||
this.mNotificationService.setIsInForeground(this.mOnConversationUpdates.size() > 0);
|
this.mNotificationService.setIsInForeground(this.mOnConversationUpdates.size() > 0);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
|
@ -1908,17 +1913,19 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) {
|
public void setOnShowErrorToastListener(OnShowErrorToast listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnShowErrorToasts.add(onShowErrorToast);
|
if (!this.mOnShowErrorToasts.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnShowErrorToastListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) {
|
public void removeOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnShowErrorToasts.remove(onShowErrorToast);
|
this.mOnShowErrorToasts.remove(onShowErrorToast);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -1927,16 +1934,18 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnAccountListChangedListener(OnAccountUpdate listener) {
|
public void setOnAccountListChangedListener(OnAccountUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnAccountUpdates.add(listener);
|
if (!this.mOnAccountUpdates.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnAccountListChangedtListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnAccountListChangedListener(OnAccountUpdate listener) {
|
public void removeOnAccountListChangedListener(OnAccountUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnAccountUpdates.remove(listener);
|
this.mOnAccountUpdates.remove(listener);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -1945,16 +1954,18 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnCaptchaRequestedListener(OnCaptchaRequested listener) {
|
public void setOnCaptchaRequestedListener(OnCaptchaRequested listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnCaptchaRequested.add(listener);
|
if (!this.mOnCaptchaRequested.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnCaptchaRequestListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnCaptchaRequestedListener(OnCaptchaRequested listener) {
|
public void removeOnCaptchaRequestedListener(OnCaptchaRequested listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnCaptchaRequested.remove(listener);
|
this.mOnCaptchaRequested.remove(listener);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -1963,16 +1974,18 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnRosterUpdateListener(final OnRosterUpdate listener) {
|
public void setOnRosterUpdateListener(final OnRosterUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnRosterUpdates.add(listener);
|
if (!this.mOnRosterUpdates.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnRosterUpdateListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnRosterUpdateListener(final OnRosterUpdate listener) {
|
public void removeOnRosterUpdateListener(final OnRosterUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnRosterUpdates.remove(listener);
|
this.mOnRosterUpdates.remove(listener);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -1981,16 +1994,18 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
|
public void setOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnUpdateBlocklist.add(listener);
|
if (!this.mOnUpdateBlocklist.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnUpdateBlocklistListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
|
public void removeOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnUpdateBlocklist.remove(listener);
|
this.mOnUpdateBlocklist.remove(listener);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -1999,16 +2014,18 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) {
|
public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnKeyStatusUpdated.add(listener);
|
if (!this.mOnKeyStatusUpdated.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnKeyStatusUpdateListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnNewKeysAvailableListener(final OnKeyStatusUpdated listener) {
|
public void removeOnNewKeysAvailableListener(final OnKeyStatusUpdated listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnKeyStatusUpdated.remove(listener);
|
this.mOnKeyStatusUpdated.remove(listener);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -2017,16 +2034,18 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
|
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
}
|
}
|
||||||
this.mOnMucRosterUpdate.add(listener);
|
if (!this.mOnMucRosterUpdate.add(listener)) {
|
||||||
|
Log.w(Config.LOGTAG,listener.getClass().getName()+" is already registered as OnMucRosterListener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeOnMucRosterUpdateListener(final OnMucRosterUpdate listener) {
|
public void removeOnMucRosterUpdateListener(final OnMucRosterUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (LISTENER_LOCK) {
|
||||||
this.mOnMucRosterUpdate.remove(listener);
|
this.mOnMucRosterUpdate.remove(listener);
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToBackground();
|
switchToBackground();
|
||||||
|
@ -2039,6 +2058,7 @@ public class XmppConnectionService extends Service {
|
||||||
&& this.mOnConversationUpdates.size() == 0
|
&& this.mOnConversationUpdates.size() == 0
|
||||||
&& this.mOnRosterUpdates.size() == 0
|
&& this.mOnRosterUpdates.size() == 0
|
||||||
&& this.mOnCaptchaRequested.size() == 0
|
&& this.mOnCaptchaRequested.size() == 0
|
||||||
|
&& this.mOnMucRosterUpdate.size() == 0
|
||||||
&& this.mOnUpdateBlocklist.size() == 0
|
&& this.mOnUpdateBlocklist.size() == 0
|
||||||
&& this.mOnShowErrorToasts.size() == 0
|
&& this.mOnShowErrorToasts.size() == 0
|
||||||
&& this.mOnKeyStatusUpdated.size() == 0);
|
&& this.mOnKeyStatusUpdated.size() == 0);
|
||||||
|
@ -3205,57 +3225,73 @@ public class XmppConnectionService extends Service {
|
||||||
|
|
||||||
|
|
||||||
public void showErrorToastInUi(int resId) {
|
public void showErrorToastInUi(int resId) {
|
||||||
for(OnShowErrorToast listener : this.mOnShowErrorToasts) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.onShowErrorToast(resId);
|
for (OnShowErrorToast listener : this.mOnShowErrorToasts) {
|
||||||
|
listener.onShowErrorToast(resId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateConversationUi() {
|
public void updateConversationUi() {
|
||||||
for(OnConversationUpdate listener : this.mOnConversationUpdates) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.onConversationUpdate();
|
for (OnConversationUpdate listener : this.mOnConversationUpdates) {
|
||||||
|
listener.onConversationUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateAccountUi() {
|
public void updateAccountUi() {
|
||||||
for(OnAccountUpdate listener : this.mOnAccountUpdates) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.onAccountUpdate();
|
for (OnAccountUpdate listener : this.mOnAccountUpdates) {
|
||||||
|
listener.onAccountUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateRosterUi() {
|
public void updateRosterUi() {
|
||||||
for(OnRosterUpdate listener : this.mOnRosterUpdates) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.onRosterUpdate();
|
for (OnRosterUpdate listener : this.mOnRosterUpdates) {
|
||||||
|
listener.onRosterUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean displayCaptchaRequest(Account account, String id, Data data, Bitmap captcha) {
|
public boolean displayCaptchaRequest(Account account, String id, Data data, Bitmap captcha) {
|
||||||
if (mOnCaptchaRequested.size() > 0) {
|
synchronized (LISTENER_LOCK) {
|
||||||
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
|
if (mOnCaptchaRequested.size() > 0) {
|
||||||
Bitmap scaled = Bitmap.createScaledBitmap(captcha, (int) (captcha.getWidth() * metrics.scaledDensity),
|
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
|
||||||
(int) (captcha.getHeight() * metrics.scaledDensity), false);
|
Bitmap scaled = Bitmap.createScaledBitmap(captcha, (int) (captcha.getWidth() * metrics.scaledDensity),
|
||||||
for(OnCaptchaRequested listener : this.mOnCaptchaRequested) {
|
(int) (captcha.getHeight() * metrics.scaledDensity), false);
|
||||||
listener.onCaptchaRequested(account, id, data, scaled);
|
for (OnCaptchaRequested listener : this.mOnCaptchaRequested) {
|
||||||
|
listener.onCaptchaRequested(account, id, data, scaled);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateBlocklistUi(final OnUpdateBlocklist.Status status) {
|
public void updateBlocklistUi(final OnUpdateBlocklist.Status status) {
|
||||||
for(OnUpdateBlocklist listener : this.mOnUpdateBlocklist) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.OnUpdateBlocklist(status);
|
for (OnUpdateBlocklist listener : this.mOnUpdateBlocklist) {
|
||||||
|
listener.OnUpdateBlocklist(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateMucRosterUi() {
|
public void updateMucRosterUi() {
|
||||||
for(OnMucRosterUpdate listener : this.mOnMucRosterUpdate) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.onMucRosterUpdate();
|
for (OnMucRosterUpdate listener : this.mOnMucRosterUpdate) {
|
||||||
|
listener.onMucRosterUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void keyStatusUpdated(AxolotlService.FetchStatus report) {
|
public void keyStatusUpdated(AxolotlService.FetchStatus report) {
|
||||||
for(OnKeyStatusUpdated listener : this.mOnKeyStatusUpdated) {
|
synchronized (LISTENER_LOCK) {
|
||||||
listener.onKeyStatusUpdated(report);
|
for (OnKeyStatusUpdated listener : this.mOnKeyStatusUpdated) {
|
||||||
|
listener.onKeyStatusUpdated(report);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,6 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
protected static final int REQUEST_BATTERY_OP = 0x49ff;
|
protected static final int REQUEST_BATTERY_OP = 0x49ff;
|
||||||
public XmppConnectionService xmppConnectionService;
|
public XmppConnectionService xmppConnectionService;
|
||||||
public boolean xmppConnectionServiceBound = false;
|
public boolean xmppConnectionServiceBound = false;
|
||||||
protected final AtomicBoolean registeredListeners = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
protected int mColorRed;
|
protected int mColorRed;
|
||||||
|
|
||||||
|
@ -108,9 +107,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
XmppConnectionBinder binder = (XmppConnectionBinder) service;
|
XmppConnectionBinder binder = (XmppConnectionBinder) service;
|
||||||
xmppConnectionService = binder.getService();
|
xmppConnectionService = binder.getService();
|
||||||
xmppConnectionServiceBound = true;
|
xmppConnectionServiceBound = true;
|
||||||
if (registeredListeners.compareAndSet(false,true)) {
|
registerListeners();
|
||||||
registerListeners();
|
|
||||||
}
|
|
||||||
onBackendConnected();
|
onBackendConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,9 +209,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
connectToBackend();
|
connectToBackend();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (registeredListeners.compareAndSet(false,true)) {
|
this.registerListeners();
|
||||||
this.registerListeners();
|
|
||||||
}
|
|
||||||
this.onBackendConnected();
|
this.onBackendConnected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,9 +225,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
if (xmppConnectionServiceBound) {
|
if (xmppConnectionServiceBound) {
|
||||||
if (registeredListeners.compareAndSet(true, false)) {
|
this.unregisterListeners();
|
||||||
this.unregisterListeners();
|
|
||||||
}
|
|
||||||
unbindService(mConnection);
|
unbindService(mConnection);
|
||||||
xmppConnectionServiceBound = false;
|
xmppConnectionServiceBound = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue