Detailed changes
@@ -1889,18 +1889,16 @@ public class XmppConnectionService extends Service {
public void requestEasyOnboardingInvite(
final Account account, final EasyOnboardingInvite.OnInviteRequested callback) {
- final XmppConnection connection = account.getXmppConnection();
- final Jid jid =
- connection == null
- ? null
- : connection.getJidForCommand(Namespace.EASY_ONBOARDING_INVITE);
- if (jid == null) {
+ final var connection = account.getXmppConnection();
+ final var discoManager = connection.getManager(DiscoManager.class);
+ final var address = discoManager.getAddressForCommand(Namespace.EASY_ONBOARDING_INVITE);
+ if (address == null) {
callback.inviteRequestFailed(
getString(R.string.server_does_not_support_easy_onboarding_invites));
return;
}
final Iq request = new Iq(Iq.Type.SET);
- request.setTo(jid);
+ request.setTo(address);
final Element command = request.addChild("command", Namespace.COMMANDS);
command.setAttribute("node", Namespace.EASY_ONBOARDING_INVITE);
command.setAttribute("action", "execute");
@@ -1922,7 +1920,7 @@ public class XmppConnectionService extends Service {
if (uri != null) {
final EasyOnboardingInvite invite =
new EasyOnboardingInvite(
- jid.getDomain().toString(), uri, landingUrl);
+ address.getDomain().toString(), uri, landingUrl);
callback.inviteRequested(invite);
return;
}
@@ -523,8 +523,7 @@ public class ContactDetailsActivity extends OmemoActivity
final String account = contact.getAccount().getJid().asBareJid().toString();
binding.detailsAccount.setOnClickListener(this::onDetailsAccountClicked);
binding.detailsAccount.setText(getString(R.string.using_account, account));
- AvatarWorkerTask.loadAvatar(
- contact, binding.detailsAvatar, R.dimen.publish_avatar_size);
+ AvatarWorkerTask.loadAvatar(contact, binding.detailsAvatar, R.dimen.publish_avatar_size);
binding.detailsAvatar.setOnClickListener(this::onAvatarClicked);
if (QuickConversationsService.isContactListIntegration(this)) {
if (contact.getSystemAccount() == null) {
@@ -2,17 +2,16 @@ package eu.siacs.conversations.utils;
import android.os.Parcel;
import android.os.Parcelable;
-
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
-
-import java.util.Collections;
-import java.util.List;
-
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.services.XmppConnectionService;
-import eu.siacs.conversations.xmpp.XmppConnection;
+import eu.siacs.conversations.xml.Namespace;
+import eu.siacs.conversations.xmpp.manager.DiscoManager;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
public class EasyOnboardingInvite implements Parcelable {
@@ -44,50 +43,53 @@ public class EasyOnboardingInvite implements Parcelable {
return 0;
}
- public static final Creator<EasyOnboardingInvite> CREATOR = new Creator<EasyOnboardingInvite>() {
- @Override
- public EasyOnboardingInvite createFromParcel(Parcel in) {
- return new EasyOnboardingInvite(in);
- }
+ public static final Creator<EasyOnboardingInvite> CREATOR =
+ new Creator<EasyOnboardingInvite>() {
+ @Override
+ public EasyOnboardingInvite createFromParcel(Parcel in) {
+ return new EasyOnboardingInvite(in);
+ }
- @Override
- public EasyOnboardingInvite[] newArray(int size) {
- return new EasyOnboardingInvite[size];
- }
- };
+ @Override
+ public EasyOnboardingInvite[] newArray(int size) {
+ return new EasyOnboardingInvite[size];
+ }
+ };
public static boolean anyHasSupport(final XmppConnectionService service) {
if (QuickConversationsService.isQuicksy()) {
return false;
}
- return getSupportingAccounts(service).size() > 0;
-
+ return !getSupportingAccounts(service).isEmpty();
}
public static List<Account> getSupportingAccounts(final XmppConnectionService service) {
- final ImmutableList.Builder<Account> supportingAccountsBuilder = new ImmutableList.Builder<>();
- final List<Account> accounts = service == null ? Collections.emptyList() : service.getAccounts();
- for(Account account : accounts) {
- final XmppConnection xmppConnection = account.getXmppConnection();
- if (xmppConnection != null && xmppConnection.getFeatures().easyOnboardingInvites()) {
+ final ImmutableList.Builder<Account> supportingAccountsBuilder =
+ new ImmutableList.Builder<>();
+ final List<Account> accounts =
+ service == null ? Collections.emptyList() : service.getAccounts();
+ for (final var account : accounts) {
+ final var connection = account.getXmppConnection();
+ final var discoManager = connection.getManager(DiscoManager.class);
+ if (Objects.nonNull(
+ discoManager.getAddressForCommand(Namespace.EASY_ONBOARDING_INVITE))) {
supportingAccountsBuilder.add(account);
}
}
return supportingAccountsBuilder.build();
}
-
public String getShareableLink() {
return Strings.isNullOrEmpty(landingUrl) ? uri : landingUrl;
}
-
public String getDomain() {
return domain;
}
public interface OnInviteRequested {
void inviteRequested(EasyOnboardingInvite invite);
+
void inviteRequestFailed(String message);
}
}
@@ -131,12 +131,10 @@ import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -161,7 +159,6 @@ public class XmppConnection implements Runnable {
protected final Account account;
private final Features features = new Features(this);
- private final HashMap<String, Jid> commands = new HashMap<>();
private final SparseArray<Stanza> mStanzaQueue = new SparseArray<>();
private final Hashtable<String, Pair<Iq, Consumer<Iq>>> packetCallbacks = new Hashtable<>();
private final Set<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners =
@@ -295,12 +292,6 @@ public class XmppConnection implements Runnable {
this.changeState(state, false);
}
- public Jid getJidForCommand(final String node) {
- synchronized (this.commands) {
- return this.commands.get(node);
- }
- }
-
public void prepareNewConnection() {
this.lastConnectionStarted = SystemClock.elapsedRealtime();
this.lastPingSent = SystemClock.elapsedRealtime();
@@ -1957,9 +1948,6 @@ public class XmppConnection implements Runnable {
}
this.redirectionUrl = null;
getManager(DiscoManager.class).clear();
- synchronized (this.commands) {
- this.commands.clear();
- }
this.loginInfo = null;
}
@@ -2255,32 +2243,6 @@ public class XmppConnection implements Runnable {
});
}
- private void discoverCommands() {
- // TODO move result handling into DiscoManager too
- final var future =
- getManager(DiscoManager.class).commands(Entity.discoItem(account.getDomain()));
- Futures.addCallback(
- future,
- new FutureCallback<>() {
- @Override
- public void onSuccess(Map<String, Jid> result) {
- synchronized (XmppConnection.this.commands) {
- XmppConnection.this.commands.clear();
- XmppConnection.this.commands.putAll(result);
- }
- }
-
- @Override
- public void onFailure(@NonNull Throwable throwable) {
- Log.d(
- Config.LOGTAG,
- account.getJid().asBareJid() + ": could not fetch commands",
- throwable);
- }
- },
- MoreExecutors.directExecutor());
- }
-
public boolean isMamPreferenceAlways() {
return isMamPreferenceAlways;
}
@@ -2312,8 +2274,9 @@ public class XmppConnection implements Runnable {
if (carbonsManager.hasFeature() && !carbonsManager.isEnabled()) {
carbonsManager.enable();
}
- if (getFeatures().commands()) {
- discoverCommands();
+ final var discoManager = getManager(DiscoManager.class);
+ if (discoManager.hasServerCommands()) {
+ discoManager.fetchServerCommands();
}
}
@@ -2998,16 +2961,6 @@ public class XmppConnection implements Runnable {
return infoQuery != null && infoQuery.getFeatureStrings().contains(feature);
}
- public boolean commands() {
- return hasDiscoFeature(account.getDomain(), Namespace.COMMANDS);
- }
-
- public boolean easyOnboardingInvites() {
- synchronized (commands) {
- return commands.containsKey(Namespace.EASY_ONBOARDING_INVITE);
- }
- }
-
public boolean blocking() {
return connection.getManager(BlockingManager.class).hasFeature();
}
@@ -10,6 +10,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.io.BaseEncoding;
+import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
@@ -91,6 +92,7 @@ public class DiscoManager extends AbstractManager {
private final Map<Jid, InfoQuery> entityInformation = new HashMap<>();
private final Map<Jid, ImmutableSet<Jid>> discoItems = new HashMap<>();
+ private final Map<String, Jid> commands = new HashMap<>();
public DiscoManager(Context context, XmppConnection connection) {
super(context, connection);
@@ -447,10 +449,19 @@ public class DiscoManager extends AbstractManager {
}
}
+ public Jid getAddressForCommand(final String node) {
+ synchronized (this.commands) {
+ return this.commands.get(node);
+ }
+ }
+
public void clear() {
synchronized (this.entityInformation) {
this.entityInformation.clear();
}
+ synchronized (this.commands) {
+ this.commands.clear();
+ }
}
public void clear(final Jid address) {
@@ -478,6 +489,34 @@ public class DiscoManager extends AbstractManager {
return Iterables.getFirst(items.entrySet(), null);
}
+ public boolean hasServerCommands() {
+ return hasServerFeature(Namespace.COMMANDS);
+ }
+
+ public void fetchServerCommands() {
+ final var future = commands(Entity.discoItem(getAccount().getDomain()));
+ Futures.addCallback(
+ future,
+ new FutureCallback<>() {
+ @Override
+ public void onSuccess(Map<String, Jid> result) {
+ synchronized (commands) {
+ commands.clear();
+ commands.putAll(result);
+ }
+ }
+
+ @Override
+ public void onFailure(@androidx.annotation.NonNull Throwable throwable) {
+ Log.d(
+ Config.LOGTAG,
+ getAccount().getJid().asBareJid() + ": could not fetch commands",
+ throwable);
+ }
+ },
+ MoreExecutors.directExecutor());
+ }
+
public static final class CapsHashMismatchException extends IllegalStateException {
public CapsHashMismatchException(final String message) {
super(message);