organize listeners in lists

This commit is contained in:
Daniel Gultsch 2018-05-03 14:54:22 +02:00
parent 5e1cbf8514
commit 157d644750
2 changed files with 94 additions and 166 deletions

View file

@ -226,7 +226,6 @@ public class XmppConnectionService extends Service {
private AvatarService mAvatarService = new AvatarService(this); private AvatarService mAvatarService = new AvatarService(this);
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
private PushManagementService mPushManagementService = new PushManagementService(this); private PushManagementService mPushManagementService = new PushManagementService(this);
private OnConversationUpdate mOnConversationUpdate = null;
private final ConversationsFileObserver fileObserver = new ConversationsFileObserver( private final ConversationsFileObserver fileObserver = new ConversationsFileObserver(
Environment.getExternalStorageDirectory().getAbsolutePath() Environment.getExternalStorageDirectory().getAbsolutePath()
) { ) {
@ -249,21 +248,20 @@ public class XmppConnectionService extends Service {
} }
} }
}; };
private int convChangedListenerCount = 0;
private OnShowErrorToast mOnShowErrorToast = null;
private int showErrorToastListenerCount = 0;
private int unreadCount = -1; private int unreadCount = -1;
private OnAccountUpdate mOnAccountUpdate = null;
private OnCaptchaRequested mOnCaptchaRequested = null; //Ui callback listeners
private int accountChangedListenerCount = 0; private final List<OnConversationUpdate> mOnConversationUpdates = new ArrayList<>();
private int captchaRequestedListenerCount = 0; private final List<OnShowErrorToast> mOnShowErrorToasts = new ArrayList<>();
private OnRosterUpdate mOnRosterUpdate = null; private final List<OnAccountUpdate> mOnAccountUpdates = new ArrayList<>();
private OnUpdateBlocklist mOnUpdateBlocklist = null; private final List<OnCaptchaRequested> mOnCaptchaRequested = new ArrayList<>();
private int updateBlocklistListenerCount = 0; private final List<OnRosterUpdate> mOnRosterUpdates = new ArrayList<>();
private int rosterChangedListenerCount = 0; private final List<OnUpdateBlocklist> mOnUpdateBlocklist = new ArrayList<>();
private OnMucRosterUpdate mOnMucRosterUpdate = null; private final List<OnMucRosterUpdate> mOnMucRosterUpdate = new ArrayList<>();
private int mucRosterChangedListenerCount = 0; private final List<OnKeyStatusUpdated> mOnKeyStatusUpdated = new ArrayList<>();
private OnKeyStatusUpdated mOnKeyStatusUpdated = null;
private final OnBindListener mOnBindListener = new OnBindListener() { private final OnBindListener mOnBindListener = new OnBindListener() {
@Override @Override
@ -302,7 +300,6 @@ public class XmppConnectionService extends Service {
syncDirtyContacts(account); syncDirtyContacts(account);
} }
}; };
private int keyStatusUpdatedListenerCount = 0;
private AtomicLong mLastExpiryRun = new AtomicLong(0); private AtomicLong mLastExpiryRun = new AtomicLong(0);
private SecureRandom mRandom; private SecureRandom mRandom;
private LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20); private LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
@ -311,9 +308,7 @@ public class XmppConnectionService extends Service {
@Override @Override
public void onStatusChanged(final Account account) { public void onStatusChanged(final Account account) {
XmppConnection connection = account.getXmppConnection(); XmppConnection connection = account.getXmppConnection();
if (mOnAccountUpdate != null) { updateAccountUi();
mOnAccountUpdate.onAccountUpdate();
}
if (account.getStatus() == Account.State.ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
synchronized (mLowPingTimeoutMode) { synchronized (mLowPingTimeoutMode) {
if (mLowPingTimeoutMode.remove(account.getJid().asBareJid())) { if (mLowPingTimeoutMode.remove(account.getJid().asBareJid())) {
@ -1881,212 +1876,155 @@ public class XmppConnectionService extends Service {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnConversationUpdate = listener; this.mOnConversationUpdates.add(listener);
this.mNotificationService.setIsInForeground(true); this.mNotificationService.setIsInForeground(this.mOnConversationUpdates.size() > 0);
if (this.convChangedListenerCount < 2) {
this.convChangedListenerCount++;
}
} }
} }
public void removeOnConversationListChangedListener() { public void removeOnConversationListChangedListener(OnConversationUpdate listener) {
synchronized (this) { synchronized (this) {
this.convChangedListenerCount--; this.mOnConversationUpdates.remove(listener);
if (this.convChangedListenerCount <= 0) { this.mNotificationService.setIsInForeground(this.mOnConversationUpdates.size() > 0);
this.convChangedListenerCount = 0;
this.mOnConversationUpdate = null;
this.mNotificationService.setIsInForeground(false);
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) { public void setOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnShowErrorToast = onShowErrorToast; this.mOnShowErrorToasts.add(onShowErrorToast);
if (this.showErrorToastListenerCount < 2) {
this.showErrorToastListenerCount++;
} }
} }
this.mOnShowErrorToast = onShowErrorToast;
}
public void removeOnShowErrorToastListener() { public void removeOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) {
synchronized (this) { synchronized (this) {
this.showErrorToastListenerCount--; this.mOnShowErrorToasts.remove(onShowErrorToast);
if (this.showErrorToastListenerCount <= 0) {
this.showErrorToastListenerCount = 0;
this.mOnShowErrorToast = null;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnAccountListChangedListener(OnAccountUpdate listener) { public void setOnAccountListChangedListener(OnAccountUpdate listener) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnAccountUpdate = listener; this.mOnAccountUpdates.add(listener);
if (this.accountChangedListenerCount < 2) {
this.accountChangedListenerCount++;
}
} }
} }
public void removeOnAccountListChangedListener() { public void removeOnAccountListChangedListener(OnAccountUpdate listener) {
synchronized (this) { synchronized (this) {
this.accountChangedListenerCount--; this.mOnAccountUpdates.remove(listener);
if (this.accountChangedListenerCount <= 0) {
this.mOnAccountUpdate = null;
this.accountChangedListenerCount = 0;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnCaptchaRequestedListener(OnCaptchaRequested listener) { public void setOnCaptchaRequestedListener(OnCaptchaRequested listener) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnCaptchaRequested = listener; this.mOnCaptchaRequested.add(listener);
if (this.captchaRequestedListenerCount < 2) {
this.captchaRequestedListenerCount++;
}
} }
} }
public void removeOnCaptchaRequestedListener() { public void removeOnCaptchaRequestedListener(OnCaptchaRequested listener) {
synchronized (this) { synchronized (this) {
this.captchaRequestedListenerCount--; this.mOnCaptchaRequested.remove(listener);
if (this.captchaRequestedListenerCount <= 0) {
this.mOnCaptchaRequested = null;
this.captchaRequestedListenerCount = 0;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnRosterUpdateListener(final OnRosterUpdate listener) { public void setOnRosterUpdateListener(final OnRosterUpdate listener) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnRosterUpdate = listener; this.mOnRosterUpdates.add(listener);
if (this.rosterChangedListenerCount < 2) {
this.rosterChangedListenerCount++;
}
} }
} }
public void removeOnRosterUpdateListener() { public void removeOnRosterUpdateListener(final OnRosterUpdate listener) {
synchronized (this) { synchronized (this) {
this.rosterChangedListenerCount--; this.mOnRosterUpdates.remove(listener);
if (this.rosterChangedListenerCount <= 0) {
this.rosterChangedListenerCount = 0;
this.mOnRosterUpdate = null;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnUpdateBlocklistListener(final OnUpdateBlocklist listener) { public void setOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnUpdateBlocklist = listener; this.mOnUpdateBlocklist.add(listener);
if (this.updateBlocklistListenerCount < 2) {
this.updateBlocklistListenerCount++;
}
} }
} }
public void removeOnUpdateBlocklistListener() { public void removeOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
synchronized (this) { synchronized (this) {
this.updateBlocklistListenerCount--; this.mOnUpdateBlocklist.remove(listener);
if (this.updateBlocklistListenerCount <= 0) {
this.updateBlocklistListenerCount = 0;
this.mOnUpdateBlocklist = null;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) { public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnKeyStatusUpdated = listener; this.mOnKeyStatusUpdated.add(listener);
if (this.keyStatusUpdatedListenerCount < 2) {
this.keyStatusUpdatedListenerCount++;
}
} }
} }
public void removeOnNewKeysAvailableListener() { public void removeOnNewKeysAvailableListener(final OnKeyStatusUpdated listener) {
synchronized (this) { synchronized (this) {
this.keyStatusUpdatedListenerCount--; this.mOnKeyStatusUpdated.remove(listener);
if (this.keyStatusUpdatedListenerCount <= 0) {
this.keyStatusUpdatedListenerCount = 0;
this.mOnKeyStatusUpdated = null;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) { public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
synchronized (this) { synchronized (this) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
} }
this.mOnMucRosterUpdate = listener; this.mOnMucRosterUpdate.add(listener);
if (this.mucRosterChangedListenerCount < 2) {
this.mucRosterChangedListenerCount++;
}
} }
} }
public void removeOnMucRosterUpdateListener() { public void removeOnMucRosterUpdateListener(final OnMucRosterUpdate listener) {
synchronized (this) { synchronized (this) {
this.mucRosterChangedListenerCount--; this.mOnMucRosterUpdate.remove(listener);
if (this.mucRosterChangedListenerCount <= 0) {
this.mucRosterChangedListenerCount = 0;
this.mOnMucRosterUpdate = null;
if (checkListeners()) { if (checkListeners()) {
switchToBackground(); switchToBackground();
} }
} }
} }
}
public boolean checkListeners() { public boolean checkListeners() {
return (this.mOnAccountUpdate == null return (this.mOnAccountUpdates.size() == 0
&& this.mOnConversationUpdate == null && this.mOnConversationUpdates.size() == 0
&& this.mOnRosterUpdate == null && this.mOnRosterUpdates.size() == 0
&& this.mOnCaptchaRequested == null && this.mOnCaptchaRequested.size() == 0
&& this.mOnUpdateBlocklist == null && this.mOnUpdateBlocklist.size() == 0
&& this.mOnShowErrorToast == null && this.mOnShowErrorToasts.size() == 0
&& this.mOnKeyStatusUpdated == null); && this.mOnKeyStatusUpdated.size() == 0);
} }
private void switchToForeground() { private void switchToForeground() {
@ -3185,56 +3123,57 @@ public class XmppConnectionService extends Service {
public void showErrorToastInUi(int resId) { public void showErrorToastInUi(int resId) {
if (mOnShowErrorToast != null) { for(OnShowErrorToast listener : this.mOnShowErrorToasts) {
mOnShowErrorToast.onShowErrorToast(resId); listener.onShowErrorToast(resId);
} }
} }
public void updateConversationUi() { public void updateConversationUi() {
if (mOnConversationUpdate != null) { for(OnConversationUpdate listener : this.mOnConversationUpdates) {
mOnConversationUpdate.onConversationUpdate(); listener.onConversationUpdate();
} }
} }
public void updateAccountUi() { public void updateAccountUi() {
if (mOnAccountUpdate != null) { for(OnAccountUpdate listener : this.mOnAccountUpdates) {
mOnAccountUpdate.onAccountUpdate(); listener.onAccountUpdate();
} }
} }
public void updateRosterUi() { public void updateRosterUi() {
if (mOnRosterUpdate != null) { for(OnRosterUpdate listener : this.mOnRosterUpdates) {
mOnRosterUpdate.onRosterUpdate(); 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 != null) { if (mOnCaptchaRequested.size() > 0) {
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics(); DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
Bitmap scaled = Bitmap.createScaledBitmap(captcha, (int) (captcha.getWidth() * metrics.scaledDensity), Bitmap scaled = Bitmap.createScaledBitmap(captcha, (int) (captcha.getWidth() * metrics.scaledDensity),
(int) (captcha.getHeight() * metrics.scaledDensity), false); (int) (captcha.getHeight() * metrics.scaledDensity), false);
for(OnCaptchaRequested listener : this.mOnCaptchaRequested) {
mOnCaptchaRequested.onCaptchaRequested(account, id, data, scaled); 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) {
if (mOnUpdateBlocklist != null) { for(OnUpdateBlocklist listener : this.mOnUpdateBlocklist) {
mOnUpdateBlocklist.OnUpdateBlocklist(status); listener.OnUpdateBlocklist(status);
} }
} }
public void updateMucRosterUi() { public void updateMucRosterUi() {
if (mOnMucRosterUpdate != null) { for(OnMucRosterUpdate listener : this.mOnMucRosterUpdate) {
mOnMucRosterUpdate.onMucRosterUpdate(); listener.onMucRosterUpdate();
} }
} }
public void keyStatusUpdated(AxolotlService.FetchStatus report) { public void keyStatusUpdated(AxolotlService.FetchStatus report) {
if (mOnKeyStatusUpdated != null) { for(OnKeyStatusUpdated listener : this.mOnKeyStatusUpdated) {
mOnKeyStatusUpdated.onKeyStatusUpdated(report); listener.onKeyStatusUpdated(report);
} }
} }

View file

@ -52,6 +52,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
@ -82,7 +83,7 @@ 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 boolean registeredListeners = false; protected final AtomicBoolean registeredListeners = new AtomicBoolean(false);
protected int mColorRed; protected int mColorRed;
@ -103,9 +104,8 @@ 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 && shouldRegisterListeners()) { if (registeredListeners.compareAndSet(false,true)) {
registerListeners(); registerListeners();
registeredListeners = true;
} }
onBackendConnected(); onBackendConnected();
} }
@ -208,23 +208,13 @@ public abstract class XmppActivity extends ActionBarActivity {
connectToBackend(); connectToBackend();
} }
} else { } else {
if (!registeredListeners) { if (registeredListeners.compareAndSet(false,true)) {
this.registerListeners(); this.registerListeners();
this.registeredListeners = true;
} }
this.onBackendConnected(); this.onBackendConnected();
} }
} }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
protected boolean shouldRegisterListeners() {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return !isDestroyed() && !isFinishing();
} else {
return !isFinishing();
}
}
public void connectToBackend() { public void connectToBackend() {
Intent intent = new Intent(this, XmppConnectionService.class); Intent intent = new Intent(this, XmppConnectionService.class);
intent.setAction("ui"); intent.setAction("ui");
@ -236,9 +226,8 @@ public abstract class XmppActivity extends ActionBarActivity {
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
if (xmppConnectionServiceBound) { if (xmppConnectionServiceBound) {
if (registeredListeners) { if (registeredListeners.compareAndSet(true, false)) {
this.unregisterListeners(); this.unregisterListeners();
this.registeredListeners = false;
} }
unbindService(mConnection); unbindService(mConnection);
xmppConnectionServiceBound = false; xmppConnectionServiceBound = false;
@ -320,28 +309,28 @@ public abstract class XmppActivity extends ActionBarActivity {
protected void unregisterListeners() { protected void unregisterListeners() {
if (this instanceof XmppConnectionService.OnConversationUpdate) { if (this instanceof XmppConnectionService.OnConversationUpdate) {
this.xmppConnectionService.removeOnConversationListChangedListener(); this.xmppConnectionService.removeOnConversationListChangedListener((XmppConnectionService.OnConversationUpdate) this);
} }
if (this instanceof XmppConnectionService.OnAccountUpdate) { if (this instanceof XmppConnectionService.OnAccountUpdate) {
this.xmppConnectionService.removeOnAccountListChangedListener(); this.xmppConnectionService.removeOnAccountListChangedListener((XmppConnectionService.OnAccountUpdate) this);
} }
if (this instanceof XmppConnectionService.OnCaptchaRequested) { if (this instanceof XmppConnectionService.OnCaptchaRequested) {
this.xmppConnectionService.removeOnCaptchaRequestedListener(); this.xmppConnectionService.removeOnCaptchaRequestedListener((XmppConnectionService.OnCaptchaRequested) this);
} }
if (this instanceof XmppConnectionService.OnRosterUpdate) { if (this instanceof XmppConnectionService.OnRosterUpdate) {
this.xmppConnectionService.removeOnRosterUpdateListener(); this.xmppConnectionService.removeOnRosterUpdateListener((XmppConnectionService.OnRosterUpdate) this);
} }
if (this instanceof XmppConnectionService.OnMucRosterUpdate) { if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
this.xmppConnectionService.removeOnMucRosterUpdateListener(); this.xmppConnectionService.removeOnMucRosterUpdateListener((XmppConnectionService.OnMucRosterUpdate) this);
} }
if (this instanceof OnUpdateBlocklist) { if (this instanceof OnUpdateBlocklist) {
this.xmppConnectionService.removeOnUpdateBlocklistListener(); this.xmppConnectionService.removeOnUpdateBlocklistListener((OnUpdateBlocklist) this);
} }
if (this instanceof XmppConnectionService.OnShowErrorToast) { if (this instanceof XmppConnectionService.OnShowErrorToast) {
this.xmppConnectionService.removeOnShowErrorToastListener(); this.xmppConnectionService.removeOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this);
} }
if (this instanceof OnKeyStatusUpdated) { if (this instanceof OnKeyStatusUpdated) {
this.xmppConnectionService.removeOnNewKeysAvailableListener(); this.xmppConnectionService.removeOnNewKeysAvailableListener((OnKeyStatusUpdated) this);
} }
} }