@@ -2,22 +2,8 @@ package eu.siacs.conversations.parser;
import android.util.Log;
import android.util.Pair;
-
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-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;
-
import eu.siacs.conversations.AppSettings;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@@ -47,22 +33,36 @@ import eu.siacs.conversations.xml.LocalizedContent;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.InvalidJid;
import eu.siacs.conversations.xmpp.Jid;
-import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
import eu.siacs.conversations.xmpp.chatstate.ChatState;
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
import eu.siacs.conversations.xmpp.pep.Avatar;
import im.conversations.android.xmpp.model.Extension;
+import im.conversations.android.xmpp.model.axolotl.Encrypted;
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.occupant.OccupantId;
import im.conversations.android.xmpp.model.reactions.Reactions;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+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;
-public class MessageParser extends AbstractParser implements Consumer<im.conversations.android.xmpp.model.stanza.Message> {
+public class MessageParser extends AbstractParser
+ implements Consumer<im.conversations.android.xmpp.model.stanza.Message> {
- private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH);
+ private static final SimpleDateFormat TIME_FORMAT =
+ new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH);
private static final List<String> JINGLE_MESSAGE_ELEMENT_NAMES =
Arrays.asList("accept", "propose", "proceed", "reject", "retract", "ringing", "finish");
@@ -71,7 +71,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
super(service, account);
}
- private static String extractStanzaId(Element packet, boolean isTypeGroupChat, Conversation conversation) {
+ private static String extractStanzaId(
+ Element packet, boolean isTypeGroupChat, Conversation conversation) {
final Jid by;
final boolean safeToExtract;
if (isTypeGroupChat) {
@@ -103,11 +104,15 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
private static Jid getTrueCounterpart(Element mucUserElement, Jid fallback) {
final Element item = mucUserElement == null ? null : mucUserElement.findChild("item");
- Jid result = item == null ? null : InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"));
+ Jid result =
+ item == null ? null : InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"));
return result != null ? result : fallback;
}
- private boolean extractChatState(Conversation c, final boolean isTypeGroupChat, final im.conversations.android.xmpp.model.stanza.Message packet) {
+ private boolean extractChatState(
+ Conversation c,
+ final boolean isTypeGroupChat,
+ final im.conversations.android.xmpp.model.stanza.Message packet) {
ChatState state = ChatState.parse(packet);
if (state != null && c != null) {
final Account account = c.getAccount();
@@ -138,45 +143,76 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
return false;
}
- private Message parseAxolotlChat(Element axolotlMessage, Jid from, Conversation conversation, int status, final boolean checkedForDuplicates, boolean postpone) {
+ private Message parseAxolotlChat(
+ final Encrypted axolotlMessage,
+ final Jid from,
+ final Conversation conversation,
+ final int status,
+ final boolean checkedForDuplicates,
+ final boolean postpone) {
final AxolotlService service = conversation.getAccount().getAxolotlService();
final XmppAxolotlMessage xmppAxolotlMessage;
try {
xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlMessage, from.asBareJid());
} catch (Exception e) {
- Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": invalid omemo message received " + e.getMessage());
+ Log.d(
+ Config.LOGTAG,
+ conversation.getAccount().getJid().asBareJid()
+ + ": invalid omemo message received "
+ + e.getMessage());
return null;
}
if (xmppAxolotlMessage.hasPayload()) {
final XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage;
try {
- plaintextMessage = service.processReceivingPayloadMessage(xmppAxolotlMessage, postpone);
+ plaintextMessage =
+ service.processReceivingPayloadMessage(xmppAxolotlMessage, postpone);
} catch (BrokenSessionException e) {
if (checkedForDuplicates) {
if (service.trustedOrPreviouslyResponded(from.asBareJid())) {
service.reportBrokenSessionException(e, postpone);
- return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
+ return new Message(
+ conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
} else {
- Log.d(Config.LOGTAG, "ignoring broken session exception because contact was not trusted");
- return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
+ Log.d(
+ Config.LOGTAG,
+ "ignoring broken session exception because contact was not"
+ + " trusted");
+ return new Message(
+ conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
}
} else {
- Log.d(Config.LOGTAG, "ignoring broken session exception because checkForDuplicates failed");
+ Log.d(
+ Config.LOGTAG,
+ "ignoring broken session exception because checkForDuplicates failed");
return null;
}
} catch (NotEncryptedForThisDeviceException e) {
- return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE, status);
+ return new Message(
+ conversation, "", Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE, status);
} catch (OutdatedSenderException e) {
return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
}
if (plaintextMessage != null) {
- Message finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, status);
+ Message finishedMessage =
+ new Message(
+ conversation,
+ plaintextMessage.getPlaintext(),
+ Message.ENCRYPTION_AXOLOTL,
+ status);
finishedMessage.setFingerprint(plaintextMessage.getFingerprint());
- Log.d(Config.LOGTAG, AxolotlService.getLogprefix(finishedMessage.getConversation().getAccount()) + " Received Message with session fingerprint: " + plaintextMessage.getFingerprint());
+ Log.d(
+ Config.LOGTAG,
+ AxolotlService.getLogprefix(finishedMessage.getConversation().getAccount())
+ + " Received Message with session fingerprint: "
+ + plaintextMessage.getFingerprint());
return finishedMessage;
}
} else {
- Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": received OMEMO key transport message");
+ Log.d(
+ Config.LOGTAG,
+ conversation.getAccount().getJid().asBareJid()
+ + ": received OMEMO key transport message");
service.processReceivingKeyTransportMessage(xmppAxolotlMessage, postpone);
}
return null;
@@ -191,7 +227,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
final Jid from = InvalidJid.getNullForInvalid(invite.getAttributeAsJid("from"));
final Jid to = InvalidJid.getNullForInvalid(invite.getAttributeAsJid("to"));
if (to != null && from == null) {
- Log.d(Config.LOGTAG,"do not parse outgoing mediated invite "+message);
+ Log.d(Config.LOGTAG, "do not parse outgoing mediated invite " + message);
return null;
}
final Jid room = InvalidJid.getNullForInvalid(message.getAttributeAsJid("from"));
@@ -250,7 +286,14 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
} else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) {
Element item = items.findChild("item");
final Set<Integer> deviceIds = IqParser.deviceIds(item);
- Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received PEP device list " + deviceIds + " update from " + from + ", processing... ");
+ Log.d(
+ Config.LOGTAG,
+ AxolotlService.getLogprefix(account)
+ + "Received PEP device list "
+ + deviceIds
+ + " update from "
+ + from
+ + ", processing... ");
final AxolotlService axolotlService = account.getAxolotlService();
axolotlService.registerDevices(from, deviceIds);
} else if (Namespace.BOOKMARKS.equals(node) && account.getJid().asBareJid().equals(from)) {
@@ -260,7 +303,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
Log.w(
Config.LOGTAG,
account.getJid().asBareJid()
- + ": received storage:bookmark notification even though we opted into bookmarks:1");
+ + ": received storage:bookmark notification even though we"
+ + " opted into bookmarks:1");
}
final Element i = items.findChild("item");
final Element storage =
@@ -274,7 +318,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
- + ": ignoring bookmark PEP event because bookmark conversion was not detected");
+ + ": ignoring bookmark PEP event because bookmark conversion was"
+ + " not detected");
}
} else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
final Element item = items.findChild("item");
@@ -291,7 +336,9 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
final Jid id = InvalidJid.getNullForInvalid(retract.getAttributeAsJid("id"));
if (id != null) {
account.removeBookmark(id);
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmark for " + id);
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid() + ": deleted bookmark for " + id);
mXmppConnectionService.processDeletedBookmark(account, id);
mXmppConnectionService.updateConversationUi();
}
@@ -319,8 +366,9 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
} 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) && account.getJid().asBareJid().equals(from)) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": deleted avatar metadata node");
+ } else if (Namespace.AVATAR_METADATA.equals(node)
+ && account.getJid().asBareJid().equals(from)) {
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted avatar metadata node");
}
}
@@ -357,10 +405,13 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
mXmppConnectionService.updateAccountUi();
}
- private boolean handleErrorMessage(final Account account, final im.conversations.android.xmpp.model.stanza.Message packet) {
+ private boolean handleErrorMessage(
+ final Account account,
+ final im.conversations.android.xmpp.model.stanza.Message packet) {
if (packet.getType() == im.conversations.android.xmpp.model.stanza.Message.Type.ERROR) {
if (packet.fromServer(account)) {
- final var forwarded = getForwardedMessagePacket(packet,"received", Namespace.CARBONS);
+ final var forwarded =
+ getForwardedMessagePacket(packet, "received", Namespace.CARBONS);
if (forwarded != null) {
return handleErrorMessage(account, forwarded.first);
}
@@ -369,29 +420,51 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
final String id = packet.getId();
if (from != null && id != null) {
if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX)) {
- final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX.length());
- mXmppConnectionService.getJingleConnectionManager()
- .updateProposedSessionDiscovered(account, from, sessionId, JingleConnectionManager.DeviceDiscoveryState.FAILED);
+ final String sessionId =
+ id.substring(
+ JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX.length());
+ mXmppConnectionService
+ .getJingleConnectionManager()
+ .updateProposedSessionDiscovered(
+ account,
+ from,
+ sessionId,
+ JingleConnectionManager.DeviceDiscoveryState.FAILED);
return true;
}
if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX)) {
- final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX.length());
+ final String sessionId =
+ id.substring(
+ JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX.length());
final String message = extractErrorMessage(packet);
- mXmppConnectionService.getJingleConnectionManager().failProceed(account, from, sessionId, message);
+ mXmppConnectionService
+ .getJingleConnectionManager()
+ .failProceed(account, from, sessionId, message);
return true;
}
- mXmppConnectionService.markMessage(account,
+ mXmppConnectionService.markMessage(
+ account,
from.asBareJid(),
id,
Message.STATUS_SEND_FAILED,
extractErrorMessage(packet));
final Element error = packet.findChild("error");
- final boolean pingWorthyError = error != null && (error.hasChild("not-acceptable") || error.hasChild("remote-server-timeout") || error.hasChild("remote-server-not-found"));
+ final boolean pingWorthyError =
+ error != null
+ && (error.hasChild("not-acceptable")
+ || error.hasChild("remote-server-timeout")
+ || error.hasChild("remote-server-not-found"));
if (pingWorthyError) {
Conversation conversation = mXmppConnectionService.find(account, from);
- if (conversation != null && conversation.getMode() == Conversational.MODE_MULTI) {
+ if (conversation != null
+ && conversation.getMode() == Conversational.MODE_MULTI) {
if (conversation.getMucOptions().online()) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received ping worthy error for seemingly online muc at " + from);
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": received ping worthy error for seemingly online"
+ + " muc at "
+ + from);
mXmppConnectionService.mucSelfPingAndRejoin(conversation);
}
}
@@ -411,17 +484,24 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
Long timestamp = null;
boolean isCarbon = false;
String serverMsgId = null;
- final Element fin = original.findChild("fin", MessageArchiveService.Version.MAM_0.namespace);
+ final Element fin =
+ original.findChild("fin", MessageArchiveService.Version.MAM_0.namespace);
if (fin != null) {
- mXmppConnectionService.getMessageArchiveService().processFinLegacy(fin, original.getFrom());
+ mXmppConnectionService
+ .getMessageArchiveService()
+ .processFinLegacy(fin, original.getFrom());
return;
}
final Element result = MessageArchiveService.Version.findResult(original);
final String queryId = result == null ? null : result.getAttribute("queryid");
- final MessageArchiveService.Query query = queryId == null ? null : mXmppConnectionService.getMessageArchiveService().findQuery(queryId);
- final boolean offlineMessagesRetrieved = account.getXmppConnection().isOfflineMessagesRetrieved();
+ final MessageArchiveService.Query query =
+ queryId == null
+ ? null
+ : mXmppConnectionService.getMessageArchiveService().findQuery(queryId);
+ final boolean offlineMessagesRetrieved =
+ account.getXmppConnection().isOfflineMessagesRetrieved();
if (query != null && query.validFrom(original.getFrom())) {
- final var f = getForwardedMessagePacket(original,"result", query.version.namespace);
+ final var f = getForwardedMessagePacket(original, "result", query.version.namespace);
if (f == null) {
return;
}
@@ -433,10 +513,18 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
return;
}
} else if (query != null) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received mam result with invalid from (" + original.getFrom() + ") or queryId (" + queryId + ")");
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": received mam result with invalid from ("
+ + original.getFrom()
+ + ") or queryId ("
+ + queryId
+ + ")");
return;
} else if (original.fromServer(account)
- && original.getType() != im.conversations.android.xmpp.model.stanza.Message.Type.GROUPCHAT) {
+ && original.getType()
+ != im.conversations.android.xmpp.model.stanza.Message.Type.GROUPCHAT) {
Pair<im.conversations.android.xmpp.model.stanza.Message, Long> f;
f = getForwardedMessagePacket(original, Received.class);
f = f == null ? getForwardedMessagePacket(original, Sent.class) : f;
@@ -451,19 +539,21 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
if (timestamp == null) {
- timestamp = AbstractParser.parseTimestamp(original, AbstractParser.parseTimestamp(packet));
+ timestamp =
+ AbstractParser.parseTimestamp(original, AbstractParser.parseTimestamp(packet));
}
- final Reactions reactions = packet.getExtension(Reactions.class);
final LocalizedContent body = packet.getBody();
final Element mucUserElement = packet.findChild("x", Namespace.MUC_USER);
- final boolean isTypeGroupChat = packet.getType() == im.conversations.android.xmpp.model.stanza.Message.Type.GROUPCHAT;
+ final boolean isTypeGroupChat =
+ packet.getType()
+ == im.conversations.android.xmpp.model.stanza.Message.Type.GROUPCHAT;
final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
final Element oob = packet.findChild("x", Namespace.OOB);
final String oobUrl = oob != null ? oob.findChildContent("url") : null;
final var replace = packet.getExtension(Replace.class);
final var replacementId = replace == null ? null : replace.getId();
- final Element axolotlEncrypted = packet.findChildEnsureSingle(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
+ final var axolotlEncrypted = packet.getOnlyExtension(Encrypted.class);
int status;
final Jid counterpart;
final Jid to = packet.getTo();
@@ -482,7 +572,12 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
return;
}
if (query != null && !query.muc() && isTypeGroupChat) {
- Log.e(Config.LOGTAG, account.getJid().asBareJid() + ": received groupchat (" + from + ") message on regular MAM request. skipping");
+ Log.e(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": received groupchat ("
+ + from
+ + ") message on regular MAM request. skipping");
return;
}
final Jid mucTrueCounterPart;
@@ -511,7 +606,11 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
mucTrueCounterPart = null;
occupant = null;
}
- boolean isMucStatusMessage = InvalidJid.hasValidFrom(packet) && from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status");
+ boolean isMucStatusMessage =
+ InvalidJid.hasValidFrom(packet)
+ && from.isBareJid()
+ && mucUserElement != null
+ && mucUserElement.hasChild("status");
boolean selfAddressed;
if (packet.fromAccount(account)) {
status = Message.STATUS_SEND;
@@ -530,27 +629,60 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
final Invite invite = extractInvite(packet);
if (invite != null) {
if (invite.jid.asBareJid().equals(account.getJid().asBareJid())) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": ignore invite to "+invite.jid+" because it matches account");
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": ignore invite to "
+ + invite.jid
+ + " because it matches account");
} else if (isTypeGroupChat) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignoring invite to " + invite.jid + " because it was received as group chat");
- } else if (invite.direct && (mucUserElement != null || invite.inviter == null || mXmppConnectionService.isMuc(account, invite.inviter))) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignoring direct invite to " + invite.jid + " because it was received in MUC");
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": ignoring invite to "
+ + invite.jid
+ + " because it was received as group chat");
+ } else if (invite.direct
+ && (mucUserElement != null
+ || invite.inviter == null
+ || mXmppConnectionService.isMuc(account, invite.inviter))) {
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": ignoring direct invite to "
+ + invite.jid
+ + " because it was received in MUC");
} else {
invite.execute(account);
return;
}
}
- if (reactions == null && (body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || oobUrl != null) && !isMucStatusMessage) {
- final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain().toEscapedString());
- final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false);
+ if ((body != null
+ || pgpEncrypted != null
+ || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload"))
+ || oobUrl != null)
+ && !isMucStatusMessage) {
+ final boolean conversationIsProbablyMuc =
+ isTypeGroupChat
+ || mucUserElement != null
+ || account.getXmppConnection()
+ .getMucServersWithholdAccount()
+ .contains(counterpart.getDomain().toEscapedString());
+ final Conversation conversation =
+ mXmppConnectionService.findOrCreateConversation(
+ account,
+ counterpart.asBareJid(),
+ conversationIsProbablyMuc,
+ false,
+ query,
+ false);
final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
if (serverMsgId == null) {
serverMsgId = extractStanzaId(packet, isTypeGroupChat, conversation);
}
-
if (selfAddressed) {
// don’t store serverMsgId on reflections for edits
final var reflectedServerMsgId =
@@ -563,7 +695,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
return;
}
status = Message.STATUS_RECEIVED;
- if (remoteMsgId != null && conversation.findMessageWithRemoteId(remoteMsgId, counterpart) != null) {
+ if (remoteMsgId != null
+ && conversation.findMessageWithRemoteId(remoteMsgId, counterpart) != null) {
return;
}
}
@@ -571,11 +704,12 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
if (isTypeGroupChat) {
if (conversation.getMucOptions().isSelf(counterpart)) {
status = Message.STATUS_SEND_RECEIVED;
- isCarbon = true; //not really carbon but received from another resource
+ isCarbon = true; // not really carbon but received from another resource
// don’t store serverMsgId on reflections for edits
final var reflectedServerMsgId =
Strings.isNullOrEmpty(replacementId) ? serverMsgId : null;
- if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status, reflectedServerMsgId, body)) {
+ if (mXmppConnectionService.markMessage(
+ conversation, remoteMsgId, status, reflectedServerMsgId, body)) {
return;
} else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) {
if (body != null) {
@@ -597,17 +731,25 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
Jid origin;
Set<Jid> fallbacksBySourceId = Collections.emptySet();
if (conversationMultiMode) {
- final Jid fallback = conversation.getMucOptions().getTrueCounterpart(counterpart);
+ final Jid fallback =
+ conversation.getMucOptions().getTrueCounterpart(counterpart);
origin = getTrueCounterpart(query != null ? mucUserElement : null, fallback);
if (origin == null) {
try {
- fallbacksBySourceId = account.getAxolotlService().findCounterpartsBySourceId(XmppAxolotlMessage.parseSourceId(axolotlEncrypted));
+ fallbacksBySourceId =
+ account.getAxolotlService()
+ .findCounterpartsBySourceId(
+ XmppAxolotlMessage.parseSourceId(
+ axolotlEncrypted));
} catch (IllegalArgumentException e) {
- //ignoring
+ // ignoring
}
}
- if (origin == null && fallbacksBySourceId.size() == 0) {
- Log.d(Config.LOGTAG, "axolotl message in anonymous conference received and no possible fallbacks");
+ if (origin == null && fallbacksBySourceId.isEmpty()) {
+ Log.d(
+ Config.LOGTAG,
+ "axolotl message in anonymous conference received and no possible"
+ + " fallbacks");
return;
}
} else {
@@ -615,17 +757,40 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
origin = from;
}
- final boolean liveMessage = query == null && !isTypeGroupChat && mucUserElement == null;
- final boolean checkedForDuplicates = liveMessage || (serverMsgId != null && remoteMsgId != null && !conversation.possibleDuplicate(serverMsgId, remoteMsgId));
+ final boolean liveMessage =
+ query == null && !isTypeGroupChat && mucUserElement == null;
+ final boolean checkedForDuplicates =
+ liveMessage
+ || (serverMsgId != null
+ && remoteMsgId != null
+ && !conversation.possibleDuplicate(
+ serverMsgId, remoteMsgId));
if (origin != null) {
- message = parseAxolotlChat(axolotlEncrypted, origin, conversation, status, checkedForDuplicates, query != null);
+ message =
+ parseAxolotlChat(
+ axolotlEncrypted,
+ origin,
+ conversation,
+ status,
+ checkedForDuplicates,
+ query != null);
} else {
Message trial = null;
for (Jid fallback : fallbacksBySourceId) {
- trial = parseAxolotlChat(axolotlEncrypted, fallback, conversation, status, checkedForDuplicates && fallbacksBySourceId.size() == 1, query != null);
+ trial =
+ parseAxolotlChat(
+ axolotlEncrypted,
+ fallback,
+ conversation,
+ status,
+ checkedForDuplicates && fallbacksBySourceId.size() == 1,
+ query != null);
if (trial != null) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": decoded muc message using fallback");
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": decoded muc message using fallback");
origin = fallback;
break;
}
@@ -633,15 +798,26 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
message = trial;
}
if (message == null) {
- if (query == null && extractChatState(mXmppConnectionService.find(account, counterpart.asBareJid()), isTypeGroupChat, packet)) {
+ if (query == null
+ && extractChatState(
+ mXmppConnectionService.find(account, counterpart.asBareJid()),
+ isTypeGroupChat,
+ packet)) {
mXmppConnectionService.updateConversationUi();
}
if (query != null && status == Message.STATUS_SEND && remoteMsgId != null) {
Message previouslySent = conversation.findSentMessageWithUuid(remoteMsgId);
- if (previouslySent != null && previouslySent.getServerMsgId() == null && serverMsgId != null) {
+ if (previouslySent != null
+ && previouslySent.getServerMsgId() == null
+ && serverMsgId != null) {
previouslySent.setServerMsgId(serverMsgId);
- mXmppConnectionService.databaseBackend.updateMessage(previouslySent, false);
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": encountered previously sent OMEMO message without serverId. updating...");
+ mXmppConnectionService.databaseBackend.updateMessage(
+ previouslySent, false);
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": encountered previously sent OMEMO message without"
+ + " serverId. updating...");
}
}
return;
@@ -691,7 +867,10 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
if (trueCounterpart != null && isTypeGroupChat) {
if (trueCounterpart.asBareJid().equals(account.getJid().asBareJid())) {
- status = isTypeGroupChat ? Message.STATUS_SEND_RECEIVED : Message.STATUS_SEND;
+ status =
+ isTypeGroupChat
+ ? Message.STATUS_SEND_RECEIVED
+ : Message.STATUS_SEND;
} else {
status = Message.STATUS_RECEIVED;
message.setCarbon(false);
@@ -707,24 +886,41 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
if (replacementId != null && mXmppConnectionService.allowMessageCorrection()) {
- final Message replacedMessage = conversation.findMessageWithRemoteIdAndCounterpart(replacementId,
- counterpart,
- message.getStatus() == Message.STATUS_RECEIVED,
- message.isCarbon());
+ final Message replacedMessage =
+ conversation.findMessageWithRemoteIdAndCounterpart(
+ replacementId,
+ counterpart,
+ message.getStatus() == Message.STATUS_RECEIVED,
+ message.isCarbon());
if (replacedMessage != null) {
- final boolean fingerprintsMatch = replacedMessage.getFingerprint() == null
- || replacedMessage.getFingerprint().equals(message.getFingerprint());
- final boolean trueCountersMatch = replacedMessage.getTrueCounterpart() != null
- && message.getTrueCounterpart() != null
- && replacedMessage.getTrueCounterpart().asBareJid().equals(message.getTrueCounterpart().asBareJid());
+ final boolean fingerprintsMatch =
+ replacedMessage.getFingerprint() == null
+ || replacedMessage
+ .getFingerprint()
+ .equals(message.getFingerprint());
+ final boolean trueCountersMatch =
+ replacedMessage.getTrueCounterpart() != null
+ && message.getTrueCounterpart() != null
+ && replacedMessage
+ .getTrueCounterpart()
+ .asBareJid()
+ .equals(message.getTrueCounterpart().asBareJid());
final boolean occupantIdMatch =
replacedMessage.getOccupantId() != null
&& replacedMessage
.getOccupantId()
.equals(message.getOccupantId());
- final boolean mucUserMatches = query == null && replacedMessage.sameMucUser(message); //can not be checked when using mam
+ final boolean mucUserMatches =
+ query == null
+ && replacedMessage.sameMucUser(
+ message); // can not be checked when using mam
final boolean duplicate = conversation.hasDuplicateMessage(message);
- if (fingerprintsMatch && (trueCountersMatch || occupantIdMatch || !conversationMultiMode || mucUserMatches) && !duplicate) {
+ if (fingerprintsMatch
+ && (trueCountersMatch
+ || occupantIdMatch
+ || !conversationMultiMode
+ || mucUserMatches)
+ && !duplicate) {
synchronized (replacedMessage) {
final String uuid = replacedMessage.getUuid();
replacedMessage.setUuid(UUID.randomUUID().toString());
@@ -752,35 +948,58 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
mXmppConnectionService.updateMessage(replacedMessage, uuid);
if (mXmppConnectionService.confirmMessages()
&& replacedMessage.getStatus() == Message.STATUS_RECEIVED
- && (replacedMessage.trusted() || replacedMessage.isPrivateMessage()) //TODO do we really want to send receipts for all PMs?
+ && (replacedMessage.trusted()
+ || replacedMessage
+ .isPrivateMessage()) // TODO do we really want
+ // to send receipts for all
+ // PMs?
&& remoteMsgId != null
&& !selfAddressed
&& !isTypeGroupChat) {
processMessageReceipts(account, packet, remoteMsgId, query);
}
if (replacedMessage.getEncryption() == Message.ENCRYPTION_PGP) {
- conversation.getAccount().getPgpDecryptionService().discard(replacedMessage);
- conversation.getAccount().getPgpDecryptionService().decrypt(replacedMessage, false);
+ conversation
+ .getAccount()
+ .getPgpDecryptionService()
+ .discard(replacedMessage);
+ conversation
+ .getAccount()
+ .getPgpDecryptionService()
+ .decrypt(replacedMessage, false);
}
}
mXmppConnectionService.getNotificationService().updateNotification();
return;
} else {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received message correction but verification didn't check out");
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": received message correction but verification didn't"
+ + " check out");
}
}
}
long deletionDate = mXmppConnectionService.getAutomaticMessageDeletionDate();
if (deletionDate != 0 && message.getTimeSent() < deletionDate) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": skipping message from " + message.getCounterpart().toString() + " because it was sent prior to our deletion date");
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": skipping message from "
+ + message.getCounterpart().toString()
+ + " because it was sent prior to our deletion date");
return;
}
- boolean checkForDuplicates = (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay"))
- || message.isPrivateMessage()
- || message.getServerMsgId() != null
- || (query == null && mXmppConnectionService.getMessageArchiveService().isCatchupInProgress(conversation));
+ boolean checkForDuplicates =
+ (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay"))
+ || message.isPrivateMessage()
+ || message.getServerMsgId() != null
+ || (query == null
+ && mXmppConnectionService
+ .getMessageArchiveService()
+ .isCatchupInProgress(conversation));
if (checkForDuplicates) {
final Message duplicate = conversation.findDuplicateMessage(message);
if (duplicate != null) {
@@ -790,7 +1009,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
&& duplicate.getServerMsgId() == null
&& message.getServerMsgId() != null) {
duplicate.setServerMsgId(message.getServerMsgId());
- if (mXmppConnectionService.databaseBackend.updateMessage(duplicate, false)) {
+ if (mXmppConnectionService.databaseBackend.updateMessage(
+ duplicate, false)) {
serverMsgIdUpdated = true;
} else {
serverMsgIdUpdated = false;
@@ -799,12 +1019,18 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
} else {
serverMsgIdUpdated = false;
}
- Log.d(Config.LOGTAG, "skipping duplicate message with " + message.getCounterpart() + ". serverMsgIdUpdated=" + serverMsgIdUpdated);
+ Log.d(
+ Config.LOGTAG,
+ "skipping duplicate message with "
+ + message.getCounterpart()
+ + ". serverMsgIdUpdated="
+ + serverMsgIdUpdated);
return;
}
}
- if (query != null && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {
+ if (query != null
+ && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {
conversation.prepend(query.getActualInThisQuery(), message);
} else {
conversation.add(message);
@@ -813,7 +1039,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
query.incrementActualMessageCount();
}
- if (query == null || query.isCatchup()) { //either no mam or catchup
+ if (query == null || query.isCatchup()) { // either no mam or catchup
if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) {
mXmppConnectionService.markRead(conversation);
if (query == null) {
@@ -826,13 +1052,21 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
if (message.getEncryption() == Message.ENCRYPTION_PGP) {
- notify = conversation.getAccount().getPgpDecryptionService().decrypt(message, notify);
- } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE || message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) {
+ notify =
+ conversation
+ .getAccount()
+ .getPgpDecryptionService()
+ .decrypt(message, notify);
+ } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE
+ || message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) {
notify = false;
}
if (query == null) {
- extractChatState(mXmppConnectionService.find(account, counterpart.asBareJid()), isTypeGroupChat, packet);
+ extractChatState(
+ mXmppConnectionService.find(account, counterpart.asBareJid()),
+ isTypeGroupChat,
+ packet);
mXmppConnectionService.updateConversationUi();
}
@@ -846,8 +1080,11 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
mXmppConnectionService.databaseBackend.createMessage(message);
- final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
- if (message.trusted() && message.treatAsDownloadable() && manager.getAutoAcceptFileSize() > 0) {
+ final HttpConnectionManager manager =
+ this.mXmppConnectionService.getHttpConnectionManager();
+ if (message.trusted()
+ && message.treatAsDownloadable()
+ && manager.getAutoAcceptFileSize() > 0) {
manager.createNewDownloadConnection(message);
} else if (notify) {
if (query != null && query.isCatchup()) {
@@ -856,16 +1093,20 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
mXmppConnectionService.getNotificationService().push(message);
}
}
- } else if (!packet.hasChild("body")) { //no body
+ } else if (!packet.hasChild("body")) { // no body
- final Conversation conversation = mXmppConnectionService.find(account, from.asBareJid());
+ final Conversation conversation =
+ mXmppConnectionService.find(account, from.asBareJid());
if (axolotlEncrypted != null) {
Jid origin;
if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
- final Jid fallback = conversation.getMucOptions().getTrueCounterpart(counterpart);
+ final Jid fallback =
+ conversation.getMucOptions().getTrueCounterpart(counterpart);
origin = getTrueCounterpart(query != null ? mucUserElement : null, fallback);
if (origin == null) {
- Log.d(Config.LOGTAG, "omemo key transport message in anonymous conference received");
+ Log.d(
+ Config.LOGTAG,
+ "omemo key transport message in anonymous conference received");
return;
}
} else if (isTypeGroupChat) {
@@ -874,25 +1115,43 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
origin = from;
}
try {
- final XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlEncrypted, origin.asBareJid());
- account.getAxolotlService().processReceivingKeyTransportMessage(xmppAxolotlMessage, query != null);
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": omemo key transport message received from " + origin);
+ final XmppAxolotlMessage xmppAxolotlMessage =
+ XmppAxolotlMessage.fromElement(axolotlEncrypted, origin.asBareJid());
+ account.getAxolotlService()
+ .processReceivingKeyTransportMessage(xmppAxolotlMessage, query != null);
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": omemo key transport message received from "
+ + origin);
} catch (Exception e) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": invalid omemo key transport message received " + e.getMessage());
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": invalid omemo key transport message received "
+ + e.getMessage());
return;
}
}
- if (query == null && extractChatState(mXmppConnectionService.find(account, counterpart.asBareJid()), isTypeGroupChat, packet)) {
+ if (query == null
+ && extractChatState(
+ mXmppConnectionService.find(account, counterpart.asBareJid()),
+ isTypeGroupChat,
+ packet)) {
mXmppConnectionService.updateConversationUi();
}
if (isTypeGroupChat) {
- if (packet.hasChild("subject") && !packet.hasChild("thread")) { // We already know it has no body per above
+ if (packet.hasChild("subject")
+ && !packet.hasChild("thread")) { // We already know it has no body per above
if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0);
- final LocalizedContent subject = packet.findInternationalizedChildContentInDefaultNamespace("subject");
- if (subject != null && conversation.getMucOptions().setSubject(subject.content)) {
+ final LocalizedContent subject =
+ packet.findInternationalizedChildContentInDefaultNamespace(
+ "subject");
+ if (subject != null
+ && conversation.getMucOptions().setSubject(subject.content)) {
mXmppConnectionService.updateConversation(conversation);
}
mXmppConnectionService.updateConversationUi();
@@ -900,7 +1159,10 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
}
}
- if (conversation != null && mucUserElement != null && InvalidJid.hasValidFrom(packet) && from.isBareJid()) {
+ if (conversation != null
+ && mucUserElement != null
+ && InvalidJid.hasValidFrom(packet)
+ && from.isBareJid()) {
for (Element child : mucUserElement.getChildren()) {
if ("status".equals(child.getName())) {
try {
@@ -910,13 +1172,19 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
break;
}
} catch (Exception e) {
- //ignored
+ // ignored
}
} else if ("item".equals(child.getName())) {
MucOptions.User user = AbstractParser.parseItem(conversation, child);
- Log.d(Config.LOGTAG, account.getJid() + ": changing affiliation for "
- + user.getRealJid() + " to " + user.getAffiliation() + " in "
- + conversation.getJid().asBareJid());
+ Log.d(
+ Config.LOGTAG,
+ account.getJid()
+ + ": changing affiliation for "
+ + user.getRealJid()
+ + " to "
+ + user.getAffiliation()
+ + " in "
+ + conversation.getJid().asBareJid());
if (!user.realJidMatchesAccount()) {
boolean isNew = conversation.getMucOptions().updateUser(user);
mXmppConnectionService.getAvatarService().clear(conversation);
@@ -927,7 +1195,13 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
Jid jid = user.getRealJid();
List<Jid> cryptoTargets = conversation.getAcceptedCryptoTargets();
if (cryptoTargets.remove(user.getRealJid())) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": removed " + jid + " from crypto targets of " + conversation.getName());
+ Log.d(
+ Config.LOGTAG,
+ account.getJid().asBareJid()
+ + ": removed "
+ + jid
+ + " from crypto targets of "
+ + conversation.getName());
conversation.setAcceptedCryptoTargets(cryptoTargets);
mXmppConnectionService.updateConversation(conversation);
}
@@ -935,7 +1209,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
&& user.getRealJid() != null
&& conversation.getMucOptions().isPrivateAndNonAnonymous()
&& (contact == null || !contact.mutualPresenceSubscription())
- && account.getAxolotlService().hasEmptyDeviceList(user.getRealJid())) {
+ && account.getAxolotlService()
+ .hasEmptyDeviceList(user.getRealJid())) {
account.getAxolotlService().fetchDeviceIds(user.getRealJid());
}
}
@@ -944,7 +1219,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
if (!isTypeGroupChat) {
for (Element child : packet.getChildren()) {
- if (Namespace.JINGLE_MESSAGE.equals(child.getNamespace()) && JINGLE_MESSAGE_ELEMENT_NAMES.contains(child.getName())) {
+ if (Namespace.JINGLE_MESSAGE.equals(child.getNamespace())
+ && JINGLE_MESSAGE_ELEMENT_NAMES.contains(child.getName())) {
final String action = child.getName();
final String sessionId = child.getAttribute("id");
if (sessionId == null) {
@@ -974,7 +1250,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
if (remoteMsgId != null && !contact.isSelf() && sendReceipts) {
processMessageReceipts(account, packet, remoteMsgId, null);
}
- } else if ((query != null && query.isCatchup()) || !offlineMessagesRetrieved) {
+ } else if ((query != null && query.isCatchup())
+ || !offlineMessagesRetrieved) {
if ("propose".equals(action)) {
final Element description = child.findChild("description");
final String namespace =
@@ -1019,37 +1296,41 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
} else {
Log.d(
Config.LOGTAG,
- "unable to find original rtp session message for received propose");
+ "unable to find original rtp session message for"
+ + " received propose");
}
} else if ("finish".equals(action)) {
Log.d(
Config.LOGTAG,
- "received JMI 'finish' during MAM catch-up. Can be used to update success/failure and duration");
+ "received JMI 'finish' during MAM catch-up. Can be used to"
+ + " update success/failure and duration");
}
} else {
- //MAM reloads (non catchups
+ // MAM reloads (non catchups
if ("propose".equals(action)) {
final Element description = child.findChild("description");
- final String namespace = description == null ? null : description.getNamespace();
+ final String namespace =
+ description == null ? null : description.getNamespace();
if (Namespace.JINGLE_APPS_RTP.equals(namespace)) {
- final Conversation c = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), false, false);
- final Message preExistingMessage = c.findRtpSession(sessionId, status);
+ final Conversation c =
+ mXmppConnectionService.findOrCreateConversation(
+ account, counterpart.asBareJid(), false, false);
+ final Message preExistingMessage =
+ c.findRtpSession(sessionId, status);
if (preExistingMessage != null) {
preExistingMessage.setServerMsgId(serverMsgId);
mXmppConnectionService.updateMessage(preExistingMessage);
break;
}
- final Message message = new Message(
- c,
- status,
- Message.TYPE_RTP_SESSION,
- sessionId
- );
+ final Message message =
+ new Message(
+ c, status, Message.TYPE_RTP_SESSION, sessionId);
message.setServerMsgId(serverMsgId);
message.setTime(timestamp);
message.setBody(new RtpSessionStatus(true, 0).toString());
- if (query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {
+ if (query.getPagingOrder()
+ == MessageArchiveService.PagingOrder.REVERSE) {
c.prepend(query.getActualInThisQuery(), message);
} else {
c.add(message);