From 24d3f9e403aad3865121d6edc151692c9b835334 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 19 May 2025 09:40:32 +0200 Subject: [PATCH] move AccountStateProcessor into its own class --- .../siacs/conversations/entities/Account.java | 6 +- .../services/MessageArchiveService.java | 2 +- .../services/NotificationService.java | 2 +- .../services/XmppConnectionService.java | 180 ++---------------- .../conversations/xmpp/XmppConnection.java | 29 ++- .../xmpp/processor/AccountStateProcessor.java | 152 +++++++++++++++ 6 files changed, 185 insertions(+), 186 deletions(-) create mode 100644 src/main/java/im/conversations/android/xmpp/processor/AccountStateProcessor.java diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 043b88d2005a3624c21b26dc5c475934389295b0..f3e235573d4971934999f7a6529b88ddd3f9ff6b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -629,11 +629,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable } public Roster getRoster() { - if (xmppConnection != null) { - return xmppConnection.getManager(RosterManager.class); - } - // TODO either return stub or always put XmppConnection into Account - return null; + return xmppConnection.getManager(RosterManager.class); } public Collection getBookmarks() { diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index 502b51ef89b55bedd2386954cda5f4530f908ad4..09af262147a0756bb1043aa763de9119e0d06151 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -221,7 +221,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } } - void executePendingQueries(final Account account) { + public void executePendingQueries(final Account account) { final List pending = new ArrayList<>(); synchronized (this.pendingQueries) { for (Iterator iterator = this.pendingQueries.iterator(); iterator.hasNext(); ) { diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 277db9037d6bbf4e1fff4241247a957aad08fed8..2db57aaa69f9d471438b2438cde3a10d520f2aa8 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -1866,7 +1866,7 @@ public class NotificationService { } } - void updateErrorNotification() { + public void updateErrorNotification() { if (Config.SUPPRESS_ERROR_NOTIFICATION) { cancel(ERROR_NOTIFICATION_ID); return; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0a37de478760c9524c0985e914cc18bb6c50a9e6..77e729f251c84f20e8f5cc6d8dbe0fb3988f6edd 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1,7 +1,6 @@ package eu.siacs.conversations.services; import static eu.siacs.conversations.utils.Compatibility.s; -import static eu.siacs.conversations.utils.Random.SECURE_RANDOM; import android.Manifest; import android.annotation.SuppressLint; @@ -125,7 +124,6 @@ import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.OnContactStatusChanged; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnMessageAcknowledged; -import eu.siacs.conversations.xmpp.OnStatusChanged; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.chatstate.ChatState; @@ -219,7 +217,7 @@ public class XmppConnectionService extends Service { private static final Executor FILE_OBSERVER_EXECUTOR = Executors.newSingleThreadExecutor(); public static final Executor FILE_ATTACHMENT_EXECUTOR = Executors.newSingleThreadExecutor(); - private final ScheduledExecutorService internalPingExecutor = + public final ScheduledExecutorService internalPingExecutor = Executors.newSingleThreadScheduledExecutor(); private static final SerialSingleThreadExecutor VIDEO_COMPRESSION_EXECUTOR = new SerialSingleThreadExecutor("VideoCompression"); @@ -234,7 +232,7 @@ public class XmppConnectionService extends Service { private final IqGenerator mIqGenerator = new IqGenerator(this); private final Set mInProgressAvatarFetches = new HashSet<>(); private final Set mOmittedPepAvatarFetches = new HashSet<>(); - private final HashSet mLowPingTimeoutMode = new HashSet<>(); + public final HashSet mLowPingTimeoutMode = new HashSet<>(); private final Consumer mDefaultIqHandler = (packet) -> { if (packet.getType() != Iq.Type.RESULT) { @@ -359,148 +357,6 @@ public class XmppConnectionService extends Service { public final Set FILENAMES_TO_IGNORE_DELETION = new HashSet<>(); private final AtomicLong mLastExpiryRun = new AtomicLong(0); - private final OnStatusChanged statusListener = - new OnStatusChanged() { - - @Override - public void onStatusChanged(final Account account) { - Log.d(Config.LOGTAG, "begin onStatusChanged()"); - final var status = account.getStatus(); - if (ServiceOutageStatus.isPossibleOutage(status)) { - fetchServiceOutageStatus(account); - } - XmppConnection connection = account.getXmppConnection(); - updateAccountUi(); - - if (account.getStatus() == Account.State.ONLINE - || account.getStatus().isError()) { - mQuickConversationsService.signalAccountStateChange(); - } - - if (account.getStatus() == Account.State.ONLINE) { - synchronized (mLowPingTimeoutMode) { - if (mLowPingTimeoutMode.remove(account.getJid().asBareJid())) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() - + ": leaving low ping timeout mode"); - } - } - if (account.setShowErrorNotification(true)) { - databaseBackend.updateAccount(account); - } - mMessageArchiveService.executePendingQueries(account); - if (connection != null && connection.getFeatures().csi()) { - if (checkListeners()) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() + " sending csi//inactive"); - connection.sendInactive(); - } else { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() + " sending csi//active"); - connection.sendActive(); - } - } - List conversations = getConversations(); - for (Conversation conversation : conversations) { - final boolean inProgressJoin; - synchronized (account.inProgressConferenceJoins) { - inProgressJoin = - account.inProgressConferenceJoins.contains(conversation); - } - final boolean pendingJoin; - synchronized (account.pendingConferenceJoins) { - pendingJoin = account.pendingConferenceJoins.contains(conversation); - } - if (conversation.getAccount() == account - && !pendingJoin - && !inProgressJoin) { - sendUnsentMessages(conversation); - } - } - final List pendingLeaves; - synchronized (account.pendingConferenceLeaves) { - pendingLeaves = new ArrayList<>(account.pendingConferenceLeaves); - account.pendingConferenceLeaves.clear(); - } - for (Conversation conversation : pendingLeaves) { - leaveMuc(conversation); - } - final List pendingJoins; - synchronized (account.pendingConferenceJoins) { - pendingJoins = new ArrayList<>(account.pendingConferenceJoins); - account.pendingConferenceJoins.clear(); - } - for (Conversation conversation : pendingJoins) { - joinMuc(conversation); - } - scheduleWakeUpCall( - Config.PING_MAX_INTERVAL * 1000L, account.getUuid().hashCode()); - } else if (account.getStatus() == Account.State.OFFLINE - || account.getStatus() == Account.State.DISABLED - || account.getStatus() == Account.State.LOGGED_OUT) { - resetSendingToWaiting(account); - if (account.isConnectionEnabled() && isInLowPingTimeoutMode(account)) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() - + ": went into offline state during low ping mode." - + " reconnecting now"); - reconnectAccount(account, true, false); - } else { - final int timeToReconnect = SECURE_RANDOM.nextInt(10) + 2; - scheduleWakeUpCall(timeToReconnect, account.getUuid().hashCode()); - } - } else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { - databaseBackend.updateAccount(account); - reconnectAccount(account, true, false); - } else if (account.getStatus() != Account.State.CONNECTING - && account.getStatus() != Account.State.NO_INTERNET) { - resetSendingToWaiting(account); - if (connection != null && account.getStatus().isAttemptReconnect()) { - final boolean aggressive = - account.getStatus() == Account.State.SEE_OTHER_HOST - || hasJingleRtpConnection(account); - final int next = connection.getTimeToNextAttempt(aggressive); - final boolean lowPingTimeoutMode = isInLowPingTimeoutMode(account); - if (next <= 0) { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() - + ": error connecting account. reconnecting now." - + " lowPingTimeout=" - + lowPingTimeoutMode); - reconnectAccount(account, true, false); - } else { - final int attempt = connection.getAttempt() + 1; - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() - + ": error connecting account. try again in " - + next - + "s for the " - + attempt - + " time. lowPingTimeout=" - + lowPingTimeoutMode - + ", aggressive=" - + aggressive); - scheduleWakeUpCall(next, account.getUuid().hashCode()); - if (aggressive) { - internalPingExecutor.schedule( - XmppConnectionService.this - ::manageAccountConnectionStatesInternal, - (next * 1000L) + 50, - TimeUnit.MILLISECONDS); - } - } - } - } - getNotificationService().updateErrorNotification(); - Log.d(Config.LOGTAG, "end onStatusChanged()"); - } - }; private OpenPgpServiceConnection pgpServiceConnection; private PgpEngine mPgpEngine = null; @@ -515,7 +371,7 @@ public class XmppConnectionService extends Service { return account.getJid().asBareJid() + "_" + avatar.owner + "_" + avatar.sha1sum; } - private boolean isInLowPingTimeoutMode(Account account) { + public boolean isInLowPingTimeoutMode(Account account) { synchronized (mLowPingTimeoutMode) { return mLowPingTimeoutMode.contains(account.getJid().asBareJid()); } @@ -987,7 +843,7 @@ public class XmppConnectionService extends Service { updateConversationUi(); } - private void manageAccountConnectionStatesInternal() { + public void manageAccountConnectionStatesInternal() { manageAccountConnectionStates(ACTION_INTERNAL_PING, null); } @@ -1050,17 +906,16 @@ public class XmppConnectionService extends Service { final boolean isUiAction, final boolean isAccountPushed, final HashSet pingCandidates) { + final var connection = account.getXmppConnection(); if (!account.getStatus().isAttemptReconnect()) { return false; } final var requestCode = account.getUuid().hashCode(); if (!hasInternetConnection()) { - account.setStatus(Account.State.NO_INTERNET); - statusListener.onStatusChanged(account); + connection.setStatusAndTriggerProcessor(Account.State.NO_INTERNET); } else { if (account.getStatus() == Account.State.NO_INTERNET) { - account.setStatus(Account.State.OFFLINE); - statusListener.onStatusChanged(account); + connection.setStatusAndTriggerProcessor(Account.State.OFFLINE); } if (account.getStatus() == Account.State.ONLINE) { synchronized (mLowPingTimeoutMode) { @@ -1111,7 +966,6 @@ public class XmppConnectionService extends Service { } else if (account.getStatus() == Account.State.OFFLINE) { reconnectAccount(account, true, interactive); } else if (account.getStatus() == Account.State.CONNECTING) { - final var connection = account.getXmppConnection(); final var connectionDuration = connection.getConnectionDuration(); final var discoDuration = connection.getDiscoDuration(); final var connectionTimeout = Config.CONNECT_TIMEOUT * 1000L - connectionDuration; @@ -1128,7 +982,7 @@ public class XmppConnectionService extends Service { final boolean aggressive = account.getStatus() == Account.State.SEE_OTHER_HOST || hasJingleRtpConnection(account); - if (account.getXmppConnection().getTimeToNextAttempt(aggressive) <= 0) { + if (connection.getTimeToNextAttempt(aggressive) <= 0) { reconnectAccount(account, true, interactive); } } @@ -1146,7 +1000,7 @@ public class XmppConnectionService extends Service { } } - private void fetchServiceOutageStatus(final Account account) { + public void fetchServiceOutageStatus(final Account account) { final var sosUrl = account.getKey(Account.KEY_SOS_URL); if (Strings.isNullOrEmpty(sosUrl)) { return; @@ -1436,6 +1290,9 @@ public class XmppConnectionService extends Service { this.databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); Log.d(Config.LOGTAG, "restoring accounts..."); this.accounts = databaseBackend.getAccounts(); + for (final var account : this.accounts) { + account.setXmppConnection(createConnection(account)); + } final SharedPreferences.Editor editor = getPreferences().edit(); final boolean hasEnabledAccounts = hasEnabledAccounts(); editor.putBoolean(SystemEventReceiver.SETTING_ENABLED_ACCOUNTS, hasEnabledAccounts).apply(); @@ -1843,8 +1700,6 @@ public class XmppConnectionService extends Service { public XmppConnection createConnection(final Account account) { final XmppConnection connection = new XmppConnection(account, this); - // TODO move status listener into final variable in XmppConnection - connection.setOnStatusChangedListener(this.statusListener); connection.setOnJinglePacketReceivedListener((mJingleConnectionManager::deliverPacket)); // TODO move MessageAck into final Processor into XmppConnection connection.setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener); @@ -2077,7 +1932,7 @@ public class XmppConnectionService extends Service { } } - private void sendUnsentMessages(final Conversation conversation) { + public void sendUnsentMessages(final Conversation conversation) { conversation.findWaitingMessages(message -> resendMessage(message, true)); } @@ -2456,7 +2311,6 @@ public class XmppConnectionService extends Service { } Log.d(Config.LOGTAG, "restoring roster..."); for (final Account account : accounts) { - account.setXmppConnection(createConnection(account)); account.getXmppConnection().getManager(RosterManager.class).restore(); } getBitmapCache().evictAll(); @@ -3100,7 +2954,8 @@ public class XmppConnectionService extends Service { public boolean updateAccount(final Account account) { if (databaseBackend.updateAccount(account)) { account.setShowErrorNotification(true); - this.statusListener.onStatusChanged(account); + // TODO what was the purpose of that? will likely be triggered by reconnect anyway? + // this.statusListener.onStatusChanged(account); databaseBackend.updateAccount(account); reconnectAccountInBackground(account); updateAccountUi(); @@ -5207,7 +5062,7 @@ public class XmppConnectionService extends Service { mDatabaseWriterExecutor.execute(() -> databaseBackend.updateConversation(conversation)); } - private void reconnectAccount( + public void reconnectAccount( final Account account, final boolean force, final boolean interactive) { synchronized (account) { final XmppConnection connection = account.getXmppConnection(); @@ -5231,6 +5086,7 @@ public class XmppConnectionService extends Service { axolotlService.resetBrokenness(); } if (!hasInternet) { + // TODO should this go via XmppConnection.setStatusAndTriggerProcessor()? account.setStatus(Account.State.NO_INTERNET); } } @@ -5942,7 +5798,7 @@ public class XmppConnectionService extends Service { return this.mJingleConnectionManager; } - private boolean hasJingleRtpConnection(final Account account) { + public boolean hasJingleRtpConnection(final Account account) { return this.mJingleConnectionManager.hasJingleRtpConnection(account); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 988dc6f890256f2824f25ade832e085647feceb0..2bd84684515889eb0c69cfc3ed1e2f10dd348284 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -117,6 +117,7 @@ import im.conversations.android.xmpp.model.stanza.Stanza; import im.conversations.android.xmpp.model.streams.StreamError; import im.conversations.android.xmpp.model.tls.Proceed; import im.conversations.android.xmpp.model.tls.StartTls; +import im.conversations.android.xmpp.processor.AccountStateProcessor; import im.conversations.android.xmpp.processor.BindProcessor; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -202,10 +203,10 @@ public class XmppConnection implements Runnable { private final Consumer presenceListener; private final Consumer unregisteredIqListener; private final Consumer messageListener; + private final Consumer accountStateProcessor; private AxolotlService axolotlService; private final PgpDecryptionService pgpDecryptionService; - private OnStatusChanged statusListener = null; - private final Runnable bindListener; + private final Runnable bindProcessor; private OnMessageAcknowledged acknowledgedListener = null; private final PendingItem pendingResumeId = new PendingItem<>(); private LoginInfo loginInfo; @@ -228,7 +229,8 @@ public class XmppConnection implements Runnable { // TODO requires roster and blocking not to be handled by this this.unregisteredIqListener = new IqParser(service, this); this.messageListener = new MessageParser(service, this); - this.bindListener = new BindProcessor(service, this); + this.bindProcessor = new BindProcessor(service, this); + this.accountStateProcessor = new AccountStateProcessor(service, this); this.managers = Managers.get(service, this); this.setAxolotlService(new AxolotlService(account, service)); this.pgpDecryptionService = new PgpDecryptionService(service); @@ -282,15 +284,7 @@ public class XmppConnection implements Runnable { return; } } - if (statusListener != null) { - try { - statusListener.onStatusChanged(account); - } catch (final Exception e) { - Log.d(Config.LOGTAG, "error executing shit", e); - } - } else { - Log.d(Config.LOGTAG, "status changed listener was null"); - } + this.accountStateProcessor.accept(nextStatus); } public Jid getJidForCommand(final String node) { @@ -2366,7 +2360,7 @@ public class XmppConnection implements Runnable { private void finalizeBind() { this.offlineMessagesRetrieved = false; - this.bindListener.run(); + this.bindProcessor.run(); this.changeStatusToOnline(); } @@ -2660,10 +2654,6 @@ public class XmppConnection implements Runnable { this.jingleListener = listener; } - public void setOnStatusChangedListener(final OnStatusChanged listener) { - this.statusListener = listener; - } - public void setOnMessageAcknowledgeListener(final OnMessageAcknowledged listener) { this.acknowledgedListener = listener; } @@ -2928,6 +2918,11 @@ public class XmppConnection implements Runnable { this.addOnAdvancedStreamFeaturesAvailableListener(axolotlService); } + public void setStatusAndTriggerProcessor(final Account.State state) { + this.account.setStatus(state); + this.accountStateProcessor.accept(state); + } + private class MyKeyManager implements X509KeyManager { @Override public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) { diff --git a/src/main/java/im/conversations/android/xmpp/processor/AccountStateProcessor.java b/src/main/java/im/conversations/android/xmpp/processor/AccountStateProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..8c3cfb6ba36732bba95ffbd049448b89dda90e45 --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/processor/AccountStateProcessor.java @@ -0,0 +1,152 @@ +package im.conversations.android.xmpp.processor; + +import static eu.siacs.conversations.utils.Random.SECURE_RANDOM; + +import android.util.Log; +import eu.siacs.conversations.Config; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.http.ServiceOutageStatus; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.XmppConnection; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class AccountStateProcessor extends XmppConnection.Delegate + implements Consumer { + + private final XmppConnectionService service; + + public AccountStateProcessor(final XmppConnectionService service, XmppConnection connection) { + super(service.getApplicationContext(), connection); + this.service = service; + } + + @Override + public void accept(final Account.State status) { + final var account = getAccount(); + if (ServiceOutageStatus.isPossibleOutage(status)) { + this.service.fetchServiceOutageStatus(account); + } + this.service.updateAccountUi(); + + if (account.getStatus() == Account.State.ONLINE || account.getStatus().isError()) { + this.service.getQuickConversationsService().signalAccountStateChange(); + } + + if (account.getStatus() == Account.State.ONLINE) { + synchronized (this.service.mLowPingTimeoutMode) { + if (this.service.mLowPingTimeoutMode.remove(account.getJid().asBareJid())) { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + ": leaving low ping timeout mode"); + } + } + if (account.setShowErrorNotification(true)) { + this.service.databaseBackend.updateAccount(account); + } + this.service.getMessageArchiveService().executePendingQueries(account); + if (connection != null && connection.getFeatures().csi()) { + if (this.service.checkListeners()) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + " sending csi//inactive"); + connection.sendInactive(); + } else { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + " sending csi//active"); + connection.sendActive(); + } + } + List conversations = this.service.getConversations(); + for (Conversation conversation : conversations) { + final boolean inProgressJoin; + synchronized (account.inProgressConferenceJoins) { + inProgressJoin = account.inProgressConferenceJoins.contains(conversation); + } + final boolean pendingJoin; + synchronized (account.pendingConferenceJoins) { + pendingJoin = account.pendingConferenceJoins.contains(conversation); + } + if (conversation.getAccount() == account && !pendingJoin && !inProgressJoin) { + this.service.sendUnsentMessages(conversation); + } + } + final List pendingLeaves; + synchronized (account.pendingConferenceLeaves) { + pendingLeaves = new ArrayList<>(account.pendingConferenceLeaves); + account.pendingConferenceLeaves.clear(); + } + for (Conversation conversation : pendingLeaves) { + this.service.leaveMuc(conversation); + } + final List pendingJoins; + synchronized (account.pendingConferenceJoins) { + pendingJoins = new ArrayList<>(account.pendingConferenceJoins); + account.pendingConferenceJoins.clear(); + } + for (Conversation conversation : pendingJoins) { + this.service.joinMuc(conversation); + } + this.service.scheduleWakeUpCall( + Config.PING_MAX_INTERVAL * 1000L, account.getUuid().hashCode()); + } else if (account.getStatus() == Account.State.OFFLINE + || account.getStatus() == Account.State.DISABLED + || account.getStatus() == Account.State.LOGGED_OUT) { + this.service.resetSendingToWaiting(account); + if (account.isConnectionEnabled() && this.service.isInLowPingTimeoutMode(account)) { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + + ": went into offline state during low ping mode." + + " reconnecting now"); + this.service.reconnectAccount(account, true, false); + } else { + final int timeToReconnect = SECURE_RANDOM.nextInt(10) + 2; + this.service.scheduleWakeUpCall(timeToReconnect, account.getUuid().hashCode()); + } + } else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { + this.service.databaseBackend.updateAccount(account); + this.service.reconnectAccount(account, true, false); + } else if (account.getStatus() != Account.State.CONNECTING + && account.getStatus() != Account.State.NO_INTERNET) { + this.service.resetSendingToWaiting(account); + if (connection != null && account.getStatus().isAttemptReconnect()) { + final boolean aggressive = + account.getStatus() == Account.State.SEE_OTHER_HOST + || this.service.hasJingleRtpConnection(account); + final int next = connection.getTimeToNextAttempt(aggressive); + final boolean lowPingTimeoutMode = this.service.isInLowPingTimeoutMode(account); + if (next <= 0) { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + + ": error connecting account. reconnecting now." + + " lowPingTimeout=" + + lowPingTimeoutMode); + this.service.reconnectAccount(account, true, false); + } else { + final int attempt = connection.getAttempt() + 1; + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + + ": error connecting account. try again in " + + next + + "s for the " + + attempt + + " time. lowPingTimeout=" + + lowPingTimeoutMode + + ", aggressive=" + + aggressive); + this.service.scheduleWakeUpCall(next, account.getUuid().hashCode()); + if (aggressive) { + this.service.internalPingExecutor.schedule( + service::manageAccountConnectionStatesInternal, + (next * 1000L) + 50, + TimeUnit.MILLISECONDS); + } + } + } + } + this.service.getNotificationService().updateErrorNotification(); + } +}