diff --git a/app/src/main/java/im/conversations/android/database/model/Account.java b/app/src/main/java/im/conversations/android/database/model/Account.java index 2c0ebfa72..11e7ddf56 100644 --- a/app/src/main/java/im/conversations/android/database/model/Account.java +++ b/app/src/main/java/im/conversations/android/database/model/Account.java @@ -34,7 +34,8 @@ public class Account extends AccountIdentifier { @Override public int hashCode() { - return Objects.hashCode(super.hashCode(), randomSeed); + // careful with hashCode and equals for byte arrays + return Objects.hashCode(super.hashCode(), Arrays.hashCode(randomSeed)); } public boolean isOnion() { diff --git a/app/src/main/java/im/conversations/android/repository/AccountRepository.java b/app/src/main/java/im/conversations/android/repository/AccountRepository.java index 4226d0007..e06ba1a8d 100644 --- a/app/src/main/java/im/conversations/android/repository/AccountRepository.java +++ b/app/src/main/java/im/conversations/android/repository/AccountRepository.java @@ -15,6 +15,7 @@ import im.conversations.android.database.model.AccountIdentifier; import im.conversations.android.database.model.Connection; import im.conversations.android.tls.ScopeFingerprint; import im.conversations.android.xmpp.ConnectionPool; +import im.conversations.android.xmpp.ConnectionState; import im.conversations.android.xmpp.XmppConnection; import im.conversations.android.xmpp.manager.RegistrationManager; import java.io.IOException; @@ -129,6 +130,13 @@ public class AccountRepository extends AbstractRepository { return database.accountDao().getAccounts(); } + public ConnectionState getConnectionState(final Account account) { + return ConnectionPool.getInstance(context) + .get(account) + .transform(XmppConnection::getStatus) + .orNull(); + } + public LiveData hasNoAccounts() { return database.accountDao().hasNoAccounts(); } diff --git a/app/src/main/java/im/conversations/android/ui/model/SetupViewModel.java b/app/src/main/java/im/conversations/android/ui/model/SetupViewModel.java index c68c77bda..5cf3c952d 100644 --- a/app/src/main/java/im/conversations/android/ui/model/SetupViewModel.java +++ b/app/src/main/java/im/conversations/android/ui/model/SetupViewModel.java @@ -263,7 +263,13 @@ public class SetupViewModel extends AndroidViewModel { private void setAccount(@NonNull final Account account) { this.account = account; this.registerTrustDecisionCallback(); - // TODO if the connection is already TLS_ERROR then do a quick reconnect + final var state = this.accountRepository.getConnectionState(account); + if (Arrays.asList(ConnectionState.TLS_ERROR).contains(state)) { + LOGGER.info( + "Connection had already failed when trust decision callback was registered." + + " reconnecting"); + this.accountRepository.reconnect(account); + } this.decideNextStep(Target.ENTER_ADDRESS, account); } diff --git a/app/src/main/java/im/conversations/android/xmpp/ConnectionPool.java b/app/src/main/java/im/conversations/android/xmpp/ConnectionPool.java index 17cc9f5c2..356babfa3 100644 --- a/app/src/main/java/im/conversations/android/xmpp/ConnectionPool.java +++ b/app/src/main/java/im/conversations/android/xmpp/ConnectionPool.java @@ -138,6 +138,11 @@ public class ConnectionPool { final Set current = getAccounts(); final Set removed = Sets.difference(current, accounts); final Set added = Sets.difference(accounts, current); + LOGGER.info( + "reconfiguring. current {} added {} removed {}", + current.size(), + added.size(), + removed.size()); for (final Account account : added) { this.setupXmppConnection(context, account); } @@ -145,10 +150,14 @@ public class ConnectionPool { final Optional connectionOptional = Iterables.tryFind(connections, c -> c.getAccount().equals(account)); if (connectionOptional.isPresent()) { - final XmppConnection connection = connectionOptional.get(); + final var connection = connectionOptional.get(); + if (connections.remove(connection)) { + LOGGER.info("Removed connection for {}", account.address); + } disconnect(connection, false); } } + LOGGER.info("now managing {} connections", connections.size()); return null; }