Detailed changes
@@ -2,7 +2,6 @@ package eu.siacs.conversations.parser;
import android.util.Log;
import android.util.Pair;
-import androidx.annotation.NonNull;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import eu.siacs.conversations.AppSettings;
@@ -14,7 +13,6 @@ import eu.siacs.conversations.crypto.axolotl.NotEncryptedForThisDeviceException;
import eu.siacs.conversations.crypto.axolotl.OutdatedSenderException;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage;
import eu.siacs.conversations.entities.Account;
-import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Conversational;
@@ -26,7 +24,6 @@ import eu.siacs.conversations.entities.ReceiptRequest;
import eu.siacs.conversations.entities.RtpSessionStatus;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.services.MessageArchiveService;
-import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xml.Element;
@@ -39,25 +36,16 @@ import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
import eu.siacs.conversations.xmpp.manager.PubSubManager;
import eu.siacs.conversations.xmpp.manager.RosterManager;
-import eu.siacs.conversations.xmpp.pep.Avatar;
import im.conversations.android.xmpp.model.Extension;
-import im.conversations.android.xmpp.model.avatar.Metadata;
-import im.conversations.android.xmpp.model.axolotl.DeviceList;
import im.conversations.android.xmpp.model.axolotl.Encrypted;
-import im.conversations.android.xmpp.model.bookmark.Storage;
-import im.conversations.android.xmpp.model.bookmark2.Conference;
import im.conversations.android.xmpp.model.carbons.Received;
import im.conversations.android.xmpp.model.carbons.Sent;
import im.conversations.android.xmpp.model.correction.Replace;
import im.conversations.android.xmpp.model.forward.Forwarded;
import im.conversations.android.xmpp.model.markers.Displayed;
-import im.conversations.android.xmpp.model.nick.Nick;
import im.conversations.android.xmpp.model.occupant.OccupantId;
import im.conversations.android.xmpp.model.oob.OutOfBandData;
-import im.conversations.android.xmpp.model.pubsub.Items;
-import im.conversations.android.xmpp.model.pubsub.event.Delete;
import im.conversations.android.xmpp.model.pubsub.event.Event;
-import im.conversations.android.xmpp.model.pubsub.event.Purge;
import im.conversations.android.xmpp.model.reactions.Reactions;
import im.conversations.android.xmpp.model.receipts.Request;
import im.conversations.android.xmpp.model.unique.StanzaId;
@@ -65,10 +53,8 @@ import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
-import java.util.HashSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
@@ -257,169 +243,6 @@ public class MessageParser extends AbstractParser
return null;
}
- private void parseEvent(final Items items, final Jid from, final Account account) {
- final String node = items.getNode();
- if ("urn:xmpp:avatar:metadata".equals(node)) {
- // TODO support retract
- final var entry = items.getFirstItemWithId(Metadata.class);
- final var avatar =
- entry == null ? null : Avatar.parseMetadata(entry.getKey(), entry.getValue());
- if (avatar != null) {
- avatar.owner = from.asBareJid();
- if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
- if (account.getJid().asBareJid().equals(from)) {
- if (account.setAvatar(avatar.getFilename())) {
- mXmppConnectionService.databaseBackend.updateAccount(account);
- mXmppConnectionService.notifyAccountAvatarHasChanged(account);
- }
- mXmppConnectionService.getAvatarService().clear(account);
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateAccountUi();
- } else {
- final Contact contact = account.getRoster().getContact(from);
- if (contact.setAvatar(avatar)) {
- connection.getManager(RosterManager.class).writeToDatabaseAsync();
- mXmppConnectionService.getAvatarService().clear(contact);
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateRosterUi();
- }
- }
- } else if (mXmppConnectionService.isDataSaverDisabled()) {
- mXmppConnectionService.fetchAvatar(account, avatar);
- }
- }
- } else if (Namespace.NICK.equals(node)) {
- final var nickItem = items.getFirstItem(Nick.class);
- final String nick = nickItem == null ? null : nickItem.getContent();
- if (nick != null) {
- setNick(account, from, nick);
- }
- } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) {
- final var deviceList = items.getFirstItem(DeviceList.class);
- if (deviceList != null) {
- final Set<Integer> deviceIds = deviceList.getDeviceIds();
- Log.d(
- Config.LOGTAG,
- AxolotlService.getLogprefix(account)
- + "Received PEP device list "
- + deviceIds
- + " update from "
- + from
- + ", processing... ");
- final AxolotlService axolotlService = account.getAxolotlService();
- axolotlService.registerDevices(from, new HashSet<>(deviceIds));
- }
-
- } else if (Namespace.BOOKMARKS.equals(node) && account.getJid().asBareJid().equals(from)) {
- final var connection = account.getXmppConnection();
- if (connection.getFeatures().bookmarksConversion()) {
- if (connection.getFeatures().bookmarks2()) {
- Log.w(
- Config.LOGTAG,
- account.getJid().asBareJid()
- + ": received storage:bookmark notification even though we"
- + " opted into bookmarks:1");
- }
- final var storage = items.getFirstItem(Storage.class);
- final Map<Jid, Bookmark> bookmarks = Bookmark.parseFromStorage(storage, account);
- // mXmppConnectionService.processBookmarksInitial(account, bookmarks, true);
- Log.d(
- Config.LOGTAG,
- account.getJid().asBareJid() + ": processing bookmark PEP event");
- } else {
- Log.d(
- Config.LOGTAG,
- account.getJid().asBareJid()
- + ": ignoring bookmark PEP event because bookmark conversion was"
- + " not detected");
- }
- } else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
- final var retractions = items.getRetractions();
- for (final var item : items.getItemMap(Conference.class).entrySet()) {
- final Bookmark bookmark =
- Bookmark.parseFromItem(item.getKey(), item.getValue(), account);
- if (bookmark == null) {
- continue;
- }
- account.putBookmark(bookmark);
- mXmppConnectionService.processModifiedBookmark(bookmark);
- mXmppConnectionService.updateConversationUi();
- }
- for (final var retract : retractions) {
- final Jid id = Jid.Invalid.getNullForInvalid(retract.getAttributeAsJid("id"));
- if (id != null) {
- account.removeBookmark(id);
- Log.d(
- Config.LOGTAG,
- account.getJid().asBareJid() + ": deleted bookmark for " + id);
- // mXmppConnectionService.processDeletedBookmark(account, id);
- mXmppConnectionService.updateConversationUi();
- }
- }
- } else if (Config.MESSAGE_DISPLAYED_SYNCHRONIZATION
- && Namespace.MDS_DISPLAYED.equals(node)
- && account.getJid().asBareJid().equals(from)) {
- for (final var item :
- items.getItemMap(im.conversations.android.xmpp.model.mds.Displayed.class)
- .entrySet()) {
- mXmppConnectionService.processMdsItem(account, item);
- }
- }
- }
-
- private void parseDeleteEvent(final Delete delete, final Jid from, final Account account) {
- final String node = delete.getNode();
- if (Namespace.NICK.equals(node)) {
- setNick(account, from, null);
- } else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmarks node");
- deleteAllBookmarks(account);
- } else if (Namespace.AVATAR_METADATA.equals(node)) {
- final boolean isAccount = account.getJid().asBareJid().equals(from);
- if (isAccount) {
- account.setAvatar(null);
- mXmppConnectionService.databaseBackend.updateAccount(account);
- mXmppConnectionService.getAvatarService().clear(account);
- Log.d(
- Config.LOGTAG,
- account.getJid().asBareJid() + ": deleted avatar metadata node");
- }
- }
- }
-
- private void parsePurgeEvent(
- @NonNull final Purge purge, final Jid from, final Account account) {
- final String node = purge.getNode();
- if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": purged bookmarks");
- deleteAllBookmarks(account);
- }
- }
-
- private void deleteAllBookmarks(final Account account) {
- final var previous = account.getBookmarkedJids();
- account.setBookmarks(Collections.emptyMap());
- // mXmppConnectionService.processDeletedBookmarks(account, previous);
- }
-
- private void setNick(final Account account, final Jid user, final String nick) {
- if (user.asBareJid().equals(account.getJid().asBareJid())) {
- account.setDisplayName(nick);
- if (QuickConversationsService.isQuicksy()) {
- mXmppConnectionService.getAvatarService().clear(account);
- }
- mXmppConnectionService.checkMucRequiresRename();
- } else {
- Contact contact = account.getRoster().getContact(user);
- if (contact.setPresenceName(nick)) {
- connection.getManager(RosterManager.class).writeToDatabaseAsync();
- mXmppConnectionService.getAvatarService().clear(contact);
- }
- }
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateAccountUi();
- }
-
private boolean handleErrorMessage(
final Account account,
final im.conversations.android.xmpp.model.stanza.Message packet) {
@@ -1414,24 +1237,6 @@ public class MessageParser extends AbstractParser
if (original.hasExtension(Event.class)) {
getManager(PubSubManager.class).handleEvent(original);
}
- final var event = original.getExtension(Event.class);
- if (event != null && Jid.Invalid.hasValidFrom(original) && original.getFrom().isBareJid()) {
- final var action = event.getAction();
- final var node = action == null ? null : action.getNode();
- if (node == null) {
- Log.d(
- Config.LOGTAG,
- account.getJid().asBareJid()
- + ": no node found in PubSub event from "
- + original.getFrom());
- } else if (action instanceof Items items) {
- parseEvent(items, original.getFrom(), account);
- } else if (action instanceof Purge purge) {
- parsePurgeEvent(purge, original.getFrom(), account);
- } else if (action instanceof Delete delete) {
- parseDeleteEvent(delete, from, account);
- }
- }
final String nick = packet.findChildContent("nick", Namespace.NICK);
if (nick != null && Jid.Invalid.hasValidFrom(original)) {
@@ -142,7 +142,6 @@ import im.conversations.android.xmpp.Entity;
import im.conversations.android.xmpp.IqErrorException;
import im.conversations.android.xmpp.model.avatar.Metadata;
import im.conversations.android.xmpp.model.disco.info.InfoQuery;
-import im.conversations.android.xmpp.model.mds.Displayed;
import im.conversations.android.xmpp.model.pubsub.PubSub;
import im.conversations.android.xmpp.model.stanza.Iq;
import im.conversations.android.xmpp.model.up.Push;
@@ -1944,51 +1943,6 @@ public class XmppConnectionService extends Service {
});
}
- public void fetchMessageDisplayedSynchronization(final Account account) {
- Log.d(Config.LOGTAG, account.getJid() + ": retrieve mds");
- final var retrieve = mIqGenerator.retrieveMds();
- sendIqPacket(
- account,
- retrieve,
- (response) -> {
- if (response.getType() != Iq.Type.RESULT) {
- return;
- }
- final var pubsub = response.getExtension(PubSub.class);
- if (pubsub == null) {
- return;
- }
- final var items = pubsub.getItems();
- if (items == null) {
- return;
- }
- if (Namespace.MDS_DISPLAYED.equals(items.getNode())) {
- for (final var item :
- items.getItemMap(
- im.conversations.android.xmpp.model.mds.Displayed
- .class)
- .entrySet()) {
- processMdsItem(account, item);
- }
- }
- });
- }
-
- public void processMdsItem(final Account account, final Map.Entry<String, Displayed> item) {
- final Jid jid = Jid.Invalid.getNullForInvalid(Jid.ofOrInvalid(item.getKey()));
- if (jid == null) {
- return;
- }
- final var displayed = item.getValue();
- final var stanzaId = displayed.getStanzaId();
- final String id = stanzaId == null ? null : stanzaId.getId();
- final Conversation conversation = find(account, jid);
- if (id != null && conversation != null) {
- conversation.setDisplayState(id);
- markReadUpToStanzaId(conversation, id);
- }
- }
-
public void markReadUpToStanzaId(final Conversation conversation, final String stanzaId) {
final Message message = conversation.findMessageWithServerMsgId(stanzaId);
if (message == null) { // do we want to check if isRead?
@@ -12,6 +12,7 @@ import eu.siacs.conversations.xmpp.manager.CarbonsManager;
import eu.siacs.conversations.xmpp.manager.DiscoManager;
import eu.siacs.conversations.xmpp.manager.EntityTimeManager;
import eu.siacs.conversations.xmpp.manager.LegacyBookmarkManager;
+import eu.siacs.conversations.xmpp.manager.MessageDisplayedSynchronizationManager;
import eu.siacs.conversations.xmpp.manager.NickManager;
import eu.siacs.conversations.xmpp.manager.PepManager;
import eu.siacs.conversations.xmpp.manager.PingManager;
@@ -38,6 +39,9 @@ public class Managers {
.put(DiscoManager.class, new DiscoManager(context, connection))
.put(EntityTimeManager.class, new EntityTimeManager(context, connection))
.put(LegacyBookmarkManager.class, new LegacyBookmarkManager(context, connection))
+ .put(
+ MessageDisplayedSynchronizationManager.class,
+ new MessageDisplayedSynchronizationManager(context, connection))
.put(NickManager.class, new NickManager(context, connection))
.put(PepManager.class, new PepManager(context, connection))
.put(PingManager.class, new PingManager(context, connection))
@@ -2,7 +2,6 @@ package eu.siacs.conversations.xmpp.manager;
import android.util.Log;
import eu.siacs.conversations.Config;
-import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.XmppConnectionService;
@@ -14,7 +13,7 @@ import java.util.Set;
public class AbstractBookmarkManager extends AbstractManager {
- private final XmppConnectionService service;
+ protected final XmppConnectionService service;
protected AbstractBookmarkManager(
final XmppConnectionService service, final XmppConnection connection) {
@@ -23,7 +22,7 @@ public class AbstractBookmarkManager extends AbstractManager {
}
// TODO rename to setBookmarks?
- public void processBookmarksInitial(final Map<Jid, Bookmark> bookmarks, final boolean pep) {
+ protected void processBookmarksInitial(final Map<Jid, Bookmark> bookmarks, final boolean pep) {
final var account = getAccount();
// TODO we can internalize this getBookmarkedJid
final Set<Jid> previousBookmarks = account.getBookmarkedJids();
@@ -32,31 +31,31 @@ public class AbstractBookmarkManager extends AbstractManager {
service.processModifiedBookmark(bookmark, pep);
}
if (pep) {
- this.processDeletedBookmarks(account, previousBookmarks);
+ this.processDeletedBookmarks(previousBookmarks);
}
account.setBookmarks(bookmarks);
}
- public void processDeletedBookmarks(final Account account, final Collection<Jid> bookmarks) {
+ protected void processDeletedBookmarks(final Collection<Jid> bookmarks) {
Log.d(
Config.LOGTAG,
- account.getJid().asBareJid()
+ getAccount().getJid().asBareJid()
+ ": "
+ bookmarks.size()
+ " bookmarks have been removed");
for (final Jid bookmark : bookmarks) {
- processDeletedBookmark(account, bookmark);
+ processDeletedBookmark(bookmark);
}
}
- public void processDeletedBookmark(final Account account, final Jid jid) {
- final Conversation conversation = service.find(account, jid);
+ protected void processDeletedBookmark(final Jid jid) {
+ final Conversation conversation = service.find(getAccount(), jid);
if (conversation == null) {
return;
}
Log.d(
Config.LOGTAG,
- account.getJid().asBareJid() + ": archiving MUC " + jid + " after PEP update");
+ getAccount().getJid().asBareJid() + ": archiving MUC " + jid + " after PEP update");
this.service.archiveConversation(conversation, false);
}
}
@@ -1,15 +1,64 @@
package eu.siacs.conversations.xmpp.manager;
-import android.content.Context;
+import android.util.Log;
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.XmppConnection;
+import eu.siacs.conversations.xmpp.pep.Avatar;
+import im.conversations.android.xmpp.model.avatar.Metadata;
import im.conversations.android.xmpp.model.pubsub.Items;
public class AvatarManager extends AbstractManager {
- public AvatarManager(Context context, XmppConnection connection) {
- super(context, connection);
+ private final XmppConnectionService service;
+
+ public AvatarManager(final XmppConnectionService service, XmppConnection connection) {
+ super(service.getApplicationContext(), connection);
+ this.service = service;
+ }
+
+ public void handleItems(final Jid from, final Items items) {
+ final var account = getAccount();
+ // TODO support retract
+ final var entry = items.getFirstItemWithId(Metadata.class);
+ final var avatar =
+ entry == null ? null : Avatar.parseMetadata(entry.getKey(), entry.getValue());
+ if (avatar != null) {
+ avatar.owner = from.asBareJid();
+ if (service.getFileBackend().isAvatarCached(avatar)) {
+ if (account.getJid().asBareJid().equals(from)) {
+ if (account.setAvatar(avatar.getFilename())) {
+ service.databaseBackend.updateAccount(account);
+ service.notifyAccountAvatarHasChanged(account);
+ }
+ service.getAvatarService().clear(account);
+ service.updateConversationUi();
+ service.updateAccountUi();
+ } else {
+ final Contact contact = account.getRoster().getContact(from);
+ if (contact.setAvatar(avatar)) {
+ connection.getManager(RosterManager.class).writeToDatabaseAsync();
+ service.getAvatarService().clear(contact);
+ service.updateConversationUi();
+ service.updateRosterUi();
+ }
+ }
+ } else if (service.isDataSaverDisabled()) {
+ service.fetchAvatar(account, avatar);
+ }
+ }
}
- public void handleItems(Jid from, final Items items) {}
+ public void handleDelete(final Jid from) {
+ final var account = getAccount();
+ final boolean isAccount = account.getJid().asBareJid().equals(from);
+ if (isAccount) {
+ account.setAvatar(null);
+ getDatabase().updateAccount(account);
+ service.getAvatarService().clear(account);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted avatar metadata node");
+ }
+ }
}
@@ -1,15 +1,38 @@
package eu.siacs.conversations.xmpp.manager;
import android.content.Context;
+import android.util.Log;
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.XmppConnection;
+import im.conversations.android.xmpp.model.axolotl.DeviceList;
import im.conversations.android.xmpp.model.pubsub.Items;
+import java.util.HashSet;
+import java.util.Set;
public class AxolotlManager extends AbstractManager {
- public AxolotlManager(Context context, XmppConnection connection) {
+ public AxolotlManager(final Context context, final XmppConnection connection) {
super(context, connection);
}
- public void handleItems(Jid from, final Items items) {}
+ public void handleItems(final Jid from, final Items items) {
+ final var account = getAccount();
+ final var deviceList = items.getFirstItem(DeviceList.class);
+ if (deviceList == null) {
+ return;
+ }
+ final Set<Integer> deviceIds = deviceList.getDeviceIds();
+ Log.d(
+ Config.LOGTAG,
+ AxolotlService.getLogprefix(account)
+ + "Received PEP device list "
+ + deviceIds
+ + " update from "
+ + from
+ + ", processing... ");
+ final AxolotlService axolotlService = account.getAxolotlService();
+ axolotlService.registerDevices(from, new HashSet<>(deviceIds));
+ }
}
@@ -17,6 +17,9 @@ import im.conversations.android.xmpp.NodeConfiguration;
import im.conversations.android.xmpp.model.bookmark2.Conference;
import im.conversations.android.xmpp.model.bookmark2.Nick;
import im.conversations.android.xmpp.model.pubsub.Items;
+import im.conversations.android.xmpp.model.pubsub.event.Retract;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
public class BookmarkManager extends AbstractBookmarkManager {
@@ -54,13 +57,35 @@ public class BookmarkManager extends AbstractBookmarkManager {
}
public void handleItems(final Items items) {
- final var retractions = items.getRetractions();
- final var itemMap = items.getItemMap(Conference.class);
- if (!retractions.isEmpty()) {
- // deleteItems(retractions);
+ this.handleItems(items.getItemMap(Conference.class));
+ this.handleRetractions(items.getRetractions());
+ }
+
+ private void handleRetractions(final Collection<Retract> retractions) {
+ final var account = getAccount();
+ for (final var retract : retractions) {
+ final Jid id = Jid.Invalid.getNullForInvalid(retract.getAttributeAsJid("id"));
+ if (id != null) {
+ account.removeBookmark(id);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmark for " + id);
+ processDeletedBookmark(id);
+ service.updateConversationUi();
+ }
}
- if (!itemMap.isEmpty()) {
- // updateItems(itemMap);
+ }
+
+ private void handleItems(final Map<String, Conference> items) {
+ final var account = getAccount();
+ for (final var item : items.entrySet()) {
+ // TODO parseFromItem can be included in this Manager
+ final Bookmark bookmark =
+ Bookmark.parseFromItem(item.getKey(), item.getValue(), account);
+ if (bookmark == null) {
+ continue;
+ }
+ account.putBookmark(bookmark);
+ service.processModifiedBookmark(bookmark);
+ service.updateConversationUi();
}
}
@@ -91,5 +116,20 @@ public class BookmarkManager extends AbstractBookmarkManager {
MoreExecutors.directExecutor());
}
- public void deleteAllItems() {}
+ private void deleteAllItems() {
+ final var account = getAccount();
+ final var previous = account.getBookmarkedJids();
+ account.setBookmarks(Collections.emptyMap());
+ processDeletedBookmarks(previous);
+ }
+
+ public void handleDelete() {
+ Log.d(Config.LOGTAG, getAccount().getJid().asBareJid() + ": deleted bookmarks node");
+ this.deleteAllItems();
+ }
+
+ public void handlePurge() {
+ Log.d(Config.LOGTAG, getAccount().getJid().asBareJid() + ": purged bookmarks");
+ this.deleteAllItems();
+ }
}
@@ -1,8 +1,14 @@
package eu.siacs.conversations.xmpp.manager;
+import android.util.Log;
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.XmppConnection;
+import im.conversations.android.xmpp.model.bookmark.Storage;
import im.conversations.android.xmpp.model.pubsub.Items;
+import java.util.Map;
public class LegacyBookmarkManager extends AbstractBookmarkManager {
@@ -11,5 +17,27 @@ public class LegacyBookmarkManager extends AbstractBookmarkManager {
super(service, connection);
}
- public void handleItems(final Items items) {}
+ public void handleItems(final Items items) {
+ final var account = this.getAccount();
+ final var connection = this.connection;
+ if (connection.getFeatures().bookmarksConversion()) {
+ if (connection.getFeatures().bookmarks2()) {
+ Log.w(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": received storage:bookmark notification even though we"
+ + " opted into bookmarks:1");
+ }
+ final var storage = items.getFirstItem(Storage.class);
+ final Map<Jid, Bookmark> bookmarks = Bookmark.parseFromStorage(storage, account);
+ this.processBookmarksInitial(bookmarks, true);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": processing bookmark PEP event");
+ } else {
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": ignoring bookmark PEP event because bookmark conversion was"
+ + " not detected");
+ }
+ }
}
@@ -0,0 +1,70 @@
+package eu.siacs.conversations.xmpp.manager;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.xmpp.Jid;
+import eu.siacs.conversations.xmpp.XmppConnection;
+import im.conversations.android.xmpp.model.mds.Displayed;
+import im.conversations.android.xmpp.model.pubsub.Items;
+import java.util.Map;
+
+public class MessageDisplayedSynchronizationManager extends AbstractManager {
+
+ private final XmppConnectionService service;
+
+ public MessageDisplayedSynchronizationManager(
+ final XmppConnectionService service, XmppConnection connection) {
+ super(service.getApplicationContext(), connection);
+ this.service = service;
+ }
+
+ public void handleItems(final Items items) {
+ for (final var item : items.getItemMap(Displayed.class).entrySet()) {
+ this.processMdsItem(item);
+ }
+ }
+
+ public void processMdsItem(final Map.Entry<String, Displayed> item) {
+ final var account = getAccount();
+ final Jid jid = Jid.Invalid.getNullForInvalid(Jid.ofOrInvalid(item.getKey()));
+ if (jid == null) {
+ return;
+ }
+ final var displayed = item.getValue();
+ final var stanzaId = displayed.getStanzaId();
+ final String id = stanzaId == null ? null : stanzaId.getId();
+ final Conversation conversation = this.service.find(account, jid);
+ if (id != null && conversation != null) {
+ conversation.setDisplayState(id);
+ this.service.markReadUpToStanzaId(conversation, id);
+ }
+ }
+
+ public void fetch() {
+ final var future = getManager(PepManager.class).fetchItems(Displayed.class);
+ Futures.addCallback(
+ future,
+ new FutureCallback<>() {
+ @Override
+ public void onSuccess(Map<String, Displayed> result) {
+ for (final var entry : result.entrySet()) {
+ processMdsItem(entry);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Throwable t) {
+ Log.d(Config.LOGTAG,getAccount().getJid().asBareJid()+": could not retrieve MDS items", t);
+ }
+ },
+ MoreExecutors.directExecutor());
+ }
+}
@@ -1,8 +1,10 @@
package eu.siacs.conversations.xmpp.manager;
-import android.content.Context;
import com.google.common.base.Strings;
import com.google.common.util.concurrent.ListenableFuture;
+import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.services.QuickConversationsService;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.XmppConnection;
import im.conversations.android.xmpp.NodeConfiguration;
@@ -11,16 +13,39 @@ import im.conversations.android.xmpp.model.pubsub.Items;
public class NickManager extends AbstractManager {
- public NickManager(Context context, XmppConnection connection) {
- super(context, connection);
+ private final XmppConnectionService service;
+
+ public NickManager(final XmppConnectionService service, final XmppConnection connection) {
+ super(service.getApplicationContext(), connection);
+ this.service = service;
}
- public void handleItems(final Jid from, Items items) {
+ public void handleItems(final Jid from, final Items items) {
final var item = items.getFirstItem(Nick.class);
final var nick = item == null ? null : item.getContent();
if (from == null || Strings.isNullOrEmpty(nick)) {
return;
}
+ setNick(from, nick);
+ }
+
+ private void setNick(final Jid user, final String nick) {
+ final var account = getAccount();
+ if (user.asBareJid().equals(account.getJid().asBareJid())) {
+ account.setDisplayName(nick);
+ if (QuickConversationsService.isQuicksy()) {
+ service.getAvatarService().clear(account);
+ }
+ service.checkMucRequiresRename();
+ } else {
+ final Contact contact = account.getRoster().getContact(user);
+ if (contact.setPresenceName(nick)) {
+ connection.getManager(RosterManager.class).writeToDatabaseAsync();
+ service.getAvatarService().clear(contact);
+ }
+ }
+ service.updateConversationUi();
+ service.updateAccountUi();
}
public ListenableFuture<Void> publishNick(final String name) {
@@ -28,4 +53,8 @@ public class NickManager extends AbstractManager {
nick.setContent(name);
return getManager(PepManager.class).publishSingleton(nick, NodeConfiguration.PRESENCE);
}
+
+ public void handleDelete(final Jid from) {
+ this.setNick(from, null);
+ }
}
@@ -172,6 +172,10 @@ public class PubSubManager extends AbstractManager {
getManager(LegacyBookmarkManager.class).handleItems(items);
return;
}
+ if (connection.fromAccount(message) && Namespace.MDS_DISPLAYED.equals(node)) {
+ getManager(MessageDisplayedSynchronizationManager.class).handleItems(items);
+ return;
+ }
if (isFromBare && Namespace.AVATAR_METADATA.equals(node)) {
getManager(AvatarManager.class).handleItems(from, items);
return;
@@ -187,13 +191,29 @@ public class PubSubManager extends AbstractManager {
private void handlePurge(final Message message, final Purge purge) {
final var from = message.getFrom();
+ final var isFromBare = from == null || from.isBareJid();
final var node = purge.getNode();
if (connection.fromAccount(message) && Namespace.BOOKMARKS2.equals(node)) {
- getManager(BookmarkManager.class).deleteAllItems();
+ getManager(BookmarkManager.class).handlePurge();
}
}
- private void handleDelete(final Message message, final Delete delete) {}
+ private void handleDelete(final Message message, final Delete delete) {
+ final var from = message.getFrom();
+ final var isFromBare = from == null || from.isBareJid();
+ final var node = delete.getNode();
+ if (connection.fromAccount(message) && Namespace.BOOKMARKS2.equals(node)) {
+ getManager(BookmarkManager.class).handleDelete();
+ return;
+ }
+ if (isFromBare && Namespace.AVATAR_METADATA.equals(node)) {
+ getManager(AvatarManager.class).handleDelete(from);
+ return;
+ }
+ if (isFromBare && Namespace.NICK.equals(node)) {
+ getManager(NickManager.class).handleDelete(from);
+ }
+ }
public ListenableFuture<Void> publishSingleton(
Jid address, Extension item, final NodeConfiguration nodeConfiguration) {
@@ -8,6 +8,7 @@ import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.XmppConnection;
import eu.siacs.conversations.xmpp.manager.BookmarkManager;
+import eu.siacs.conversations.xmpp.manager.MessageDisplayedSynchronizationManager;
import eu.siacs.conversations.xmpp.manager.PrivateStorageManager;
import eu.siacs.conversations.xmpp.manager.RosterManager;
import im.conversations.android.xmpp.model.stanza.Iq;
@@ -73,7 +74,7 @@ public class BindProcessor extends XmppConnection.Delegate implements Runnable {
}
if (features.mds()) {
- service.fetchMessageDisplayedSynchronization(account);
+ connection.getManager(MessageDisplayedSynchronizationManager.class).fetch();
} else {
Log.d(Config.LOGTAG, account.getJid() + ": server has no support for mds");
}