aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/parser
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2016-11-19 23:07:54 +0100
committerChristian Schneppe <christian@pix-art.de>2016-11-19 23:07:54 +0100
commitd783cec97084a12873ca62b5fcd64620056ec01b (patch)
tree65e63d03dd4ab7a834c343ba593c8cd8917620cb /src/main/java/de/pixart/messenger/parser
parent969ba45c56adaaa056f04464cd98aec115c9611b (diff)
reformat code
Diffstat (limited to '')
-rw-r--r--src/main/java/de/pixart/messenger/parser/AbstractParser.java130
-rw-r--r--src/main/java/de/pixart/messenger/parser/IqParser.java652
-rw-r--r--src/main/java/de/pixart/messenger/parser/MessageParser.java1218
-rw-r--r--src/main/java/de/pixart/messenger/parser/PresenceParser.java454
4 files changed, 1227 insertions, 1227 deletions
diff --git a/src/main/java/de/pixart/messenger/parser/AbstractParser.java b/src/main/java/de/pixart/messenger/parser/AbstractParser.java
index 3ad20783b..21da7fe67 100644
--- a/src/main/java/de/pixart/messenger/parser/AbstractParser.java
+++ b/src/main/java/de/pixart/messenger/parser/AbstractParser.java
@@ -15,88 +15,88 @@ import de.pixart.messenger.xmpp.jid.Jid;
public abstract class AbstractParser {
- protected XmppConnectionService mXmppConnectionService;
+ protected XmppConnectionService mXmppConnectionService;
- protected AbstractParser(XmppConnectionService service) {
- this.mXmppConnectionService = service;
- }
+ protected AbstractParser(XmppConnectionService service) {
+ this.mXmppConnectionService = service;
+ }
- public static Long parseTimestamp(Element element, Long d) {
- Element delay = element.findChild("delay","urn:xmpp:delay");
- if (delay != null) {
- String stamp = delay.getAttribute("stamp");
- if (stamp != null) {
- try {
- return AbstractParser.parseTimestamp(delay.getAttribute("stamp"));
- } catch (ParseException e) {
- return d;
- }
- }
- }
- return d;
- }
+ public static Long parseTimestamp(Element element, Long d) {
+ Element delay = element.findChild("delay", "urn:xmpp:delay");
+ if (delay != null) {
+ String stamp = delay.getAttribute("stamp");
+ if (stamp != null) {
+ try {
+ return AbstractParser.parseTimestamp(delay.getAttribute("stamp"));
+ } catch (ParseException e) {
+ return d;
+ }
+ }
+ }
+ return d;
+ }
- public static long parseTimestamp(Element element) {
- return parseTimestamp(element, System.currentTimeMillis());
- }
+ public static long parseTimestamp(Element element) {
+ return parseTimestamp(element, System.currentTimeMillis());
+ }
- public static long parseTimestamp(String timestamp) throws ParseException {
- timestamp = timestamp.replace("Z", "+0000");
- SimpleDateFormat dateFormat;
- long ms;
- if (timestamp.charAt(19) == '.' && timestamp.length() >= 25) {
- String millis = timestamp.substring(19,timestamp.length() - 5);
- try {
- double fractions = Double.parseDouble("0" + millis);
- ms = Math.round(1000 * fractions);
- } catch (NumberFormatException e) {
- ms = 0;
- }
- } else {
- ms = 0;
- }
- timestamp = timestamp.substring(0,19)+timestamp.substring(timestamp.length() -5,timestamp.length());
- dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",Locale.US);
- return Math.min(dateFormat.parse(timestamp).getTime()+ms, System.currentTimeMillis());
- }
+ public static long parseTimestamp(String timestamp) throws ParseException {
+ timestamp = timestamp.replace("Z", "+0000");
+ SimpleDateFormat dateFormat;
+ long ms;
+ if (timestamp.charAt(19) == '.' && timestamp.length() >= 25) {
+ String millis = timestamp.substring(19, timestamp.length() - 5);
+ try {
+ double fractions = Double.parseDouble("0" + millis);
+ ms = Math.round(1000 * fractions);
+ } catch (NumberFormatException e) {
+ ms = 0;
+ }
+ } else {
+ ms = 0;
+ }
+ timestamp = timestamp.substring(0, 19) + timestamp.substring(timestamp.length() - 5, timestamp.length());
+ dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
+ return Math.min(dateFormat.parse(timestamp).getTime() + ms, System.currentTimeMillis());
+ }
- protected void updateLastseen(final Account account, final Jid from) {
- final Contact contact = account.getRoster().getContact(from);
- contact.setLastResource(from.isBareJid() ? "" : from.getResourcepart());
- }
+ protected void updateLastseen(final Account account, final Jid from) {
+ final Contact contact = account.getRoster().getContact(from);
+ contact.setLastResource(from.isBareJid() ? "" : from.getResourcepart());
+ }
- protected String avatarData(Element items) {
- Element item = items.findChild("item");
- if (item == null) {
- return null;
- }
- return item.findChildContent("data", "urn:xmpp:avatar:data");
- }
+ protected String avatarData(Element items) {
+ Element item = items.findChild("item");
+ if (item == null) {
+ return null;
+ }
+ return item.findChildContent("data", "urn:xmpp:avatar:data");
+ }
- public static MucOptions.User parseItem(Conversation conference, Element item) {
+ public static MucOptions.User parseItem(Conversation conference, Element item) {
return parseItem(conference, item, null);
}
public static MucOptions.User parseItem(Conversation conference, Element item, Jid fullJid) {
- final String local = conference.getJid().getLocalpart();
- final String domain = conference.getJid().getDomainpart();
- String affiliation = item.getAttribute("affiliation");
- String role = item.getAttribute("role");
- String nick = item.getAttribute("nick");
+ final String local = conference.getJid().getLocalpart();
+ final String domain = conference.getJid().getDomainpart();
+ String affiliation = item.getAttribute("affiliation");
+ String role = item.getAttribute("role");
+ String nick = item.getAttribute("nick");
if (nick != null && fullJid == null) {
try {
fullJid = Jid.fromParts(local, domain, nick);
} catch (InvalidJidException e) {
fullJid = null;
}
- }
- Jid realJid = item.getAttributeAsJid("jid");
+ }
+ Jid realJid = item.getAttributeAsJid("jid");
MucOptions.User user = new MucOptions.User(conference.getMucOptions(), fullJid);
- user.setRealJid(realJid);
- user.setAffiliation(affiliation);
- user.setRole(role);
- return user;
- }
+ user.setRealJid(realJid);
+ user.setAffiliation(affiliation);
+ user.setRole(role);
+ return user;
+ }
public static String extractErrorMessage(Element packet) {
final Element error = packet.findChild("error");
@@ -105,7 +105,7 @@ public abstract class AbstractParser {
if (text != null && !text.trim().isEmpty()) {
return text;
} else {
- return error.getChildren().get(0).getName().replace("-"," ");
+ return error.getChildren().get(0).getName().replace("-", " ");
}
} else {
return null;
diff --git a/src/main/java/de/pixart/messenger/parser/IqParser.java b/src/main/java/de/pixart/messenger/parser/IqParser.java
index 5617973d6..25d946c1d 100644
--- a/src/main/java/de/pixart/messenger/parser/IqParser.java
+++ b/src/main/java/de/pixart/messenger/parser/IqParser.java
@@ -36,351 +36,351 @@ import de.pixart.messenger.xmpp.stanzas.IqPacket;
public class IqParser extends AbstractParser implements OnIqPacketReceived {
- public IqParser(final XmppConnectionService service) {
- super(service);
- }
+ public IqParser(final XmppConnectionService service) {
+ super(service);
+ }
- private void rosterItems(final Account account, final Element query) {
- final String version = query.getAttribute("ver");
- if (version != null) {
- account.getRoster().setVersion(version);
- }
- for (final Element item : query.getChildren()) {
- if (item.getName().equals("item")) {
- final Jid jid = item.getAttributeAsJid("jid");
- if (jid == null) {
- continue;
- }
- final String name = item.getAttribute("name");
- final String subscription = item.getAttribute("subscription");
- final Contact contact = account.getRoster().getContact(jid);
- boolean bothPre = contact.getOption(Contact.Options.TO) && contact.getOption(Contact.Options.FROM);
- if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
- contact.setServerName(name);
- contact.parseGroupsFromElement(item);
- }
- if (subscription != null) {
- if (subscription.equals("remove")) {
- contact.resetOption(Contact.Options.IN_ROSTER);
- contact.resetOption(Contact.Options.DIRTY_DELETE);
- contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
- } else {
- contact.setOption(Contact.Options.IN_ROSTER);
- contact.resetOption(Contact.Options.DIRTY_PUSH);
- contact.parseSubscriptionFromElement(item);
- }
- }
- boolean both = contact.getOption(Contact.Options.TO) && contact.getOption(Contact.Options.FROM);
- if ((both != bothPre) && both) {
- Log.d(Config.LOGTAG,account.getJid().toBareJid()+": gained mutual presence subscription with "+contact.getJid());
- AxolotlService axolotlService = account.getAxolotlService();
- if (axolotlService != null) {
- axolotlService.clearErrorsInFetchStatusMap(contact.getJid());
- }
- }
- mXmppConnectionService.getAvatarService().clear(contact);
- }
- }
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateRosterUi();
- }
+ private void rosterItems(final Account account, final Element query) {
+ final String version = query.getAttribute("ver");
+ if (version != null) {
+ account.getRoster().setVersion(version);
+ }
+ for (final Element item : query.getChildren()) {
+ if (item.getName().equals("item")) {
+ final Jid jid = item.getAttributeAsJid("jid");
+ if (jid == null) {
+ continue;
+ }
+ final String name = item.getAttribute("name");
+ final String subscription = item.getAttribute("subscription");
+ final Contact contact = account.getRoster().getContact(jid);
+ boolean bothPre = contact.getOption(Contact.Options.TO) && contact.getOption(Contact.Options.FROM);
+ if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
+ contact.setServerName(name);
+ contact.parseGroupsFromElement(item);
+ }
+ if (subscription != null) {
+ if (subscription.equals("remove")) {
+ contact.resetOption(Contact.Options.IN_ROSTER);
+ contact.resetOption(Contact.Options.DIRTY_DELETE);
+ contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
+ } else {
+ contact.setOption(Contact.Options.IN_ROSTER);
+ contact.resetOption(Contact.Options.DIRTY_PUSH);
+ contact.parseSubscriptionFromElement(item);
+ }
+ }
+ boolean both = contact.getOption(Contact.Options.TO) && contact.getOption(Contact.Options.FROM);
+ if ((both != bothPre) && both) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": gained mutual presence subscription with " + contact.getJid());
+ AxolotlService axolotlService = account.getAxolotlService();
+ if (axolotlService != null) {
+ axolotlService.clearErrorsInFetchStatusMap(contact.getJid());
+ }
+ }
+ mXmppConnectionService.getAvatarService().clear(contact);
+ }
+ }
+ mXmppConnectionService.updateConversationUi();
+ mXmppConnectionService.updateRosterUi();
+ }
- public String avatarData(final IqPacket packet) {
- final Element pubsub = packet.findChild("pubsub",
- "http://jabber.org/protocol/pubsub");
- if (pubsub == null) {
- return null;
- }
- final Element items = pubsub.findChild("items");
- if (items == null) {
- return null;
- }
- return super.avatarData(items);
- }
+ public String avatarData(final IqPacket packet) {
+ final Element pubsub = packet.findChild("pubsub",
+ "http://jabber.org/protocol/pubsub");
+ if (pubsub == null) {
+ return null;
+ }
+ final Element items = pubsub.findChild("items");
+ if (items == null) {
+ return null;
+ }
+ return super.avatarData(items);
+ }
- public Element getItem(final IqPacket packet) {
- final Element pubsub = packet.findChild("pubsub",
- "http://jabber.org/protocol/pubsub");
- if (pubsub == null) {
- return null;
- }
- final Element items = pubsub.findChild("items");
- if (items == null) {
- return null;
- }
- return items.findChild("item");
- }
+ public Element getItem(final IqPacket packet) {
+ final Element pubsub = packet.findChild("pubsub",
+ "http://jabber.org/protocol/pubsub");
+ if (pubsub == null) {
+ return null;
+ }
+ final Element items = pubsub.findChild("items");
+ if (items == null) {
+ return null;
+ }
+ return items.findChild("item");
+ }
- @NonNull
- public Set<Integer> deviceIds(final Element item) {
- Set<Integer> deviceIds = new HashSet<>();
- if (item != null) {
- final Element list = item.findChild("list");
- if (list != null) {
- for (Element device : list.getChildren()) {
- if (!device.getName().equals("device")) {
- continue;
- }
- try {
- Integer id = Integer.valueOf(device.getAttribute("id"));
- deviceIds.add(id);
- } catch (NumberFormatException e) {
- Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered invalid <device> node in PEP ("+e.getMessage()+"):" + device.toString()+ ", skipping...");
- continue;
- }
- }
- }
- }
- return deviceIds;
- }
+ @NonNull
+ public Set<Integer> deviceIds(final Element item) {
+ Set<Integer> deviceIds = new HashSet<>();
+ if (item != null) {
+ final Element list = item.findChild("list");
+ if (list != null) {
+ for (Element device : list.getChildren()) {
+ if (!device.getName().equals("device")) {
+ continue;
+ }
+ try {
+ Integer id = Integer.valueOf(device.getAttribute("id"));
+ deviceIds.add(id);
+ } catch (NumberFormatException e) {
+ Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Encountered invalid <device> node in PEP (" + e.getMessage() + "):" + device.toString() + ", skipping...");
+ continue;
+ }
+ }
+ }
+ }
+ return deviceIds;
+ }
- public Integer signedPreKeyId(final Element bundle) {
- final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic");
- if(signedPreKeyPublic == null) {
- return null;
- }
+ public Integer signedPreKeyId(final Element bundle) {
+ final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic");
+ if (signedPreKeyPublic == null) {
+ return null;
+ }
try {
return Integer.valueOf(signedPreKeyPublic.getAttribute("signedPreKeyId"));
} catch (NumberFormatException e) {
return null;
}
- }
+ }
- public ECPublicKey signedPreKeyPublic(final Element bundle) {
- ECPublicKey publicKey = null;
- final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic");
- if(signedPreKeyPublic == null) {
- return null;
- }
- try {
- publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0);
- } catch (Throwable e) {
- Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid signedPreKeyPublic in PEP: " + e.getMessage());
- }
- return publicKey;
- }
+ public ECPublicKey signedPreKeyPublic(final Element bundle) {
+ ECPublicKey publicKey = null;
+ final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic");
+ if (signedPreKeyPublic == null) {
+ return null;
+ }
+ try {
+ publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(), Base64.DEFAULT), 0);
+ } catch (Throwable e) {
+ Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Invalid signedPreKeyPublic in PEP: " + e.getMessage());
+ }
+ return publicKey;
+ }
- public byte[] signedPreKeySignature(final Element bundle) {
- final Element signedPreKeySignature = bundle.findChild("signedPreKeySignature");
- if(signedPreKeySignature == null) {
- return null;
- }
- try {
- return Base64.decode(signedPreKeySignature.getContent(), Base64.DEFAULT);
- } catch (Throwable e) {
- Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : Invalid base64 in signedPreKeySignature");
- return null;
- }
- }
+ public byte[] signedPreKeySignature(final Element bundle) {
+ final Element signedPreKeySignature = bundle.findChild("signedPreKeySignature");
+ if (signedPreKeySignature == null) {
+ return null;
+ }
+ try {
+ return Base64.decode(signedPreKeySignature.getContent(), Base64.DEFAULT);
+ } catch (Throwable e) {
+ Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : Invalid base64 in signedPreKeySignature");
+ return null;
+ }
+ }
- public IdentityKey identityKey(final Element bundle) {
- IdentityKey identityKey = null;
- final Element identityKeyElement = bundle.findChild("identityKey");
- if(identityKeyElement == null) {
- return null;
- }
- try {
- identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0);
- } catch (Throwable e) {
- Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : "+"Invalid identityKey in PEP: "+e.getMessage());
- }
- return identityKey;
- }
+ public IdentityKey identityKey(final Element bundle) {
+ IdentityKey identityKey = null;
+ final Element identityKeyElement = bundle.findChild("identityKey");
+ if (identityKeyElement == null) {
+ return null;
+ }
+ try {
+ identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0);
+ } catch (Throwable e) {
+ Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Invalid identityKey in PEP: " + e.getMessage());
+ }
+ return identityKey;
+ }
- public Map<Integer, ECPublicKey> preKeyPublics(final IqPacket packet) {
- Map<Integer, ECPublicKey> preKeyRecords = new HashMap<>();
- Element item = getItem(packet);
- if (item == null) {
- Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Couldn't find <item> in bundle IQ packet: " + packet);
- return null;
- }
- final Element bundleElement = item.findChild("bundle");
- if(bundleElement == null) {
- return null;
- }
- final Element prekeysElement = bundleElement.findChild("prekeys");
- if(prekeysElement == null) {
- Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Couldn't find <prekeys> in bundle IQ packet: " + packet);
- return null;
- }
- for(Element preKeyPublicElement : prekeysElement.getChildren()) {
- if(!preKeyPublicElement.getName().equals("preKeyPublic")){
- Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered unexpected tag in prekeys list: " + preKeyPublicElement);
- continue;
- }
- Integer preKeyId = null;
- try {
- preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId"));
- final ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0);
- preKeyRecords.put(preKeyId, preKeyPublic);
- } catch (NumberFormatException e) {
- Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"could not parse preKeyId from preKey "+preKeyPublicElement.toString());
- } catch (Throwable e) {
- Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping...");
- }
- }
- return preKeyRecords;
- }
+ public Map<Integer, ECPublicKey> preKeyPublics(final IqPacket packet) {
+ Map<Integer, ECPublicKey> preKeyRecords = new HashMap<>();
+ Element item = getItem(packet);
+ if (item == null) {
+ Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Couldn't find <item> in bundle IQ packet: " + packet);
+ return null;
+ }
+ final Element bundleElement = item.findChild("bundle");
+ if (bundleElement == null) {
+ return null;
+ }
+ final Element prekeysElement = bundleElement.findChild("prekeys");
+ if (prekeysElement == null) {
+ Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Couldn't find <prekeys> in bundle IQ packet: " + packet);
+ return null;
+ }
+ for (Element preKeyPublicElement : prekeysElement.getChildren()) {
+ if (!preKeyPublicElement.getName().equals("preKeyPublic")) {
+ Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Encountered unexpected tag in prekeys list: " + preKeyPublicElement);
+ continue;
+ }
+ Integer preKeyId = null;
+ try {
+ preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId"));
+ final ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0);
+ preKeyRecords.put(preKeyId, preKeyPublic);
+ } catch (NumberFormatException e) {
+ Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "could not parse preKeyId from preKey " + preKeyPublicElement.toString());
+ } catch (Throwable e) {
+ Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Invalid preKeyPublic (ID=" + preKeyId + ") in PEP: " + e.getMessage() + ", skipping...");
+ }
+ }
+ return preKeyRecords;
+ }
- public Pair<X509Certificate[],byte[]> verification(final IqPacket packet) {
- Element item = getItem(packet);
- Element verification = item != null ? item.findChild("verification",AxolotlService.PEP_PREFIX) : null;
- Element chain = verification != null ? verification.findChild("chain") : null;
- Element signature = verification != null ? verification.findChild("signature") : null;
- if (chain != null && signature != null) {
- List<Element> certElements = chain.getChildren();
- X509Certificate[] certificates = new X509Certificate[certElements.size()];
- try {
- CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
- int i = 0;
- for(Element cert : certElements) {
- certificates[i] = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.getContent(),Base64.DEFAULT)));
- ++i;
- }
- return new Pair<>(certificates,Base64.decode(signature.getContent(),Base64.DEFAULT));
- } catch (CertificateException e) {
- return null;
- }
- } else {
- return null;
- }
- }
+ public Pair<X509Certificate[], byte[]> verification(final IqPacket packet) {
+ Element item = getItem(packet);
+ Element verification = item != null ? item.findChild("verification", AxolotlService.PEP_PREFIX) : null;
+ Element chain = verification != null ? verification.findChild("chain") : null;
+ Element signature = verification != null ? verification.findChild("signature") : null;
+ if (chain != null && signature != null) {
+ List<Element> certElements = chain.getChildren();
+ X509Certificate[] certificates = new X509Certificate[certElements.size()];
+ try {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+ int i = 0;
+ for (Element cert : certElements) {
+ certificates[i] = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.getContent(), Base64.DEFAULT)));
+ ++i;
+ }
+ return new Pair<>(certificates, Base64.decode(signature.getContent(), Base64.DEFAULT));
+ } catch (CertificateException e) {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
- public PreKeyBundle bundle(final IqPacket bundle) {
- Element bundleItem = getItem(bundle);
- if(bundleItem == null) {
- return null;
- }
- final Element bundleElement = bundleItem.findChild("bundle");
- if(bundleElement == null) {
- return null;
- }
- ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement);
- Integer signedPreKeyId = signedPreKeyId(bundleElement);
- byte[] signedPreKeySignature = signedPreKeySignature(bundleElement);
- IdentityKey identityKey = identityKey(bundleElement);
- if(signedPreKeyId == null || signedPreKeyPublic == null || identityKey == null) {
- return null;
- }
+ public PreKeyBundle bundle(final IqPacket bundle) {
+ Element bundleItem = getItem(bundle);
+ if (bundleItem == null) {
+ return null;
+ }
+ final Element bundleElement = bundleItem.findChild("bundle");
+ if (bundleElement == null) {
+ return null;
+ }
+ ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement);
+ Integer signedPreKeyId = signedPreKeyId(bundleElement);
+ byte[] signedPreKeySignature = signedPreKeySignature(bundleElement);
+ IdentityKey identityKey = identityKey(bundleElement);
+ if (signedPreKeyId == null || signedPreKeyPublic == null || identityKey == null) {
+ return null;
+ }
- return new PreKeyBundle(0, 0, 0, null,
- signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey);
- }
+ return new PreKeyBundle(0, 0, 0, null,
+ signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey);
+ }
- public List<PreKeyBundle> preKeys(final IqPacket preKeys) {
- List<PreKeyBundle> bundles = new ArrayList<>();
- Map<Integer, ECPublicKey> preKeyPublics = preKeyPublics(preKeys);
- if ( preKeyPublics != null) {
- for (Integer preKeyId : preKeyPublics.keySet()) {
- ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId);
- bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic,
- 0, null, null, null));
- }
- }
+ public List<PreKeyBundle> preKeys(final IqPacket preKeys) {
+ List<PreKeyBundle> bundles = new ArrayList<>();
+ Map<Integer, ECPublicKey> preKeyPublics = preKeyPublics(preKeys);
+ if (preKeyPublics != null) {
+ for (Integer preKeyId : preKeyPublics.keySet()) {
+ ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId);
+ bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic,
+ 0, null, null, null));
+ }
+ }
- return bundles;
- }
+ return bundles;
+ }
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- final boolean isGet = packet.getType() == IqPacket.TYPE.GET;
- if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) {
- return;
- } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) {
- final Element query = packet.findChild("query");
- // If this is in response to a query for the whole roster:
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- account.getRoster().markAllAsNotInRoster();
- }
- this.rosterItems(account, query);
- } else if ((packet.hasChild("block", Xmlns.BLOCKING) || packet.hasChild("blocklist", Xmlns.BLOCKING)) &&
- packet.fromServer(account)) {
- // Block list or block push.
- Log.d(Config.LOGTAG, "Received blocklist update from server");
- final Element blocklist = packet.findChild("blocklist", Xmlns.BLOCKING);
- final Element block = packet.findChild("block", Xmlns.BLOCKING);
- final Collection<Element> items = blocklist != null ? blocklist.getChildren() :
- (block != null ? block.getChildren() : null);
- // If this is a response to a blocklist query, clear the block list and replace with the new one.
- // Otherwise, just update the existing blocklist.
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- account.clearBlocklist();
- account.getXmppConnection().getFeatures().setBlockListRequested(true);
- }
- if (items != null) {
- final Collection<Jid> jids = new ArrayList<>(items.size());
- // Create a collection of Jids from the packet
- for (final Element item : items) {
- if (item.getName().equals("item")) {
- final Jid jid = item.getAttributeAsJid("jid");
- if (jid != null) {
- jids.add(jid);
- }
- }
- }
- account.getBlocklist().addAll(jids);
- }
- // Update the UI
- mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED);
- if (packet.getType() == IqPacket.TYPE.SET) {
- final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
- mXmppConnectionService.sendIqPacket(account, response, null);
- }
- } else if (packet.hasChild("unblock", Xmlns.BLOCKING) &&
- packet.fromServer(account) && packet.getType() == IqPacket.TYPE.SET) {
- Log.d(Config.LOGTAG, "Received unblock update from server");
- final Collection<Element> items = packet.findChild("unblock", Xmlns.BLOCKING).getChildren();
- if (items.size() == 0) {
- // No children to unblock == unblock all
- account.getBlocklist().clear();
- } else {
- final Collection<Jid> jids = new ArrayList<>(items.size());
- for (final Element item : items) {
- if (item.getName().equals("item")) {
- final Jid jid = item.getAttributeAsJid("jid");
- if (jid != null) {
- jids.add(jid);
- }
- }
- }
- account.getBlocklist().removeAll(jids);
- }
- mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED);
- final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
- mXmppConnectionService.sendIqPacket(account, response, null);
- } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
- || packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
- mXmppConnectionService.getJingleConnectionManager()
- .deliverIbbPacket(account, packet);
- } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
- final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet);
- mXmppConnectionService.sendIqPacket(account, response, null);
- } else if (packet.hasChild("query","jabber:iq:version") && isGet) {
- final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet);
- mXmppConnectionService.sendIqPacket(account,response,null);
- } else if (packet.hasChild("ping", "urn:xmpp:ping") && isGet) {
- final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
- mXmppConnectionService.sendIqPacket(account, response, null);
- } else if (packet.hasChild("time","urn:xmpp:time") && isGet) {
- final IqPacket response;
- if (mXmppConnectionService.useTorToConnect()) {
- response = packet.generateResponse(IqPacket.TYPE.ERROR);
- final Element error = response.addChild("error");
- error.setAttribute("type","cancel");
- error.addChild("not-allowed","urn:ietf:params:xml:ns:xmpp-stanzas");
- } else {
- response = mXmppConnectionService.getIqGenerator().entityTimeResponse(packet);
- }
- mXmppConnectionService.sendIqPacket(account,response, null);
- } else {
- if (packet.getType() == IqPacket.TYPE.GET || packet.getType() == IqPacket.TYPE.SET) {
- final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);
- final Element error = response.addChild("error");
- error.setAttribute("type", "cancel");
- error.addChild("feature-not-implemented","urn:ietf:params:xml:ns:xmpp-stanzas");
- account.getXmppConnection().sendIqPacket(response, null);
- }
- }
- }
+ @Override
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
+ final boolean isGet = packet.getType() == IqPacket.TYPE.GET;
+ if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) {
+ return;
+ } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) {
+ final Element query = packet.findChild("query");
+ // If this is in response to a query for the whole roster:
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ account.getRoster().markAllAsNotInRoster();
+ }
+ this.rosterItems(account, query);
+ } else if ((packet.hasChild("block", Xmlns.BLOCKING) || packet.hasChild("blocklist", Xmlns.BLOCKING)) &&
+ packet.fromServer(account)) {
+ // Block list or block push.
+ Log.d(Config.LOGTAG, "Received blocklist update from server");
+ final Element blocklist = packet.findChild("blocklist", Xmlns.BLOCKING);
+ final Element block = packet.findChild("block", Xmlns.BLOCKING);
+ final Collection<Element> items = blocklist != null ? blocklist.getChildren() :
+ (block != null ? block.getChildren() : null);
+ // If this is a response to a blocklist query, clear the block list and replace with the new one.
+ // Otherwise, just update the existing blocklist.
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ account.clearBlocklist();
+ account.getXmppConnection().getFeatures().setBlockListRequested(true);
+ }
+ if (items != null) {
+ final Collection<Jid> jids = new ArrayList<>(items.size());
+ // Create a collection of Jids from the packet
+ for (final Element item : items) {
+ if (item.getName().equals("item")) {
+ final Jid jid = item.getAttributeAsJid("jid");
+ if (jid != null) {
+ jids.add(jid);
+ }
+ }
+ }
+ account.getBlocklist().addAll(jids);
+ }
+ // Update the UI
+ mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED);
+ if (packet.getType() == IqPacket.TYPE.SET) {
+ final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ }
+ } else if (packet.hasChild("unblock", Xmlns.BLOCKING) &&
+ packet.fromServer(account) && packet.getType() == IqPacket.TYPE.SET) {
+ Log.d(Config.LOGTAG, "Received unblock update from server");
+ final Collection<Element> items = packet.findChild("unblock", Xmlns.BLOCKING).getChildren();
+ if (items.size() == 0) {
+ // No children to unblock == unblock all
+ account.getBlocklist().clear();
+ } else {
+ final Collection<Jid> jids = new ArrayList<>(items.size());
+ for (final Element item : items) {
+ if (item.getName().equals("item")) {
+ final Jid jid = item.getAttributeAsJid("jid");
+ if (jid != null) {
+ jids.add(jid);
+ }
+ }
+ }
+ account.getBlocklist().removeAll(jids);
+ }
+ mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED);
+ final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
+ || packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
+ mXmppConnectionService.getJingleConnectionManager()
+ .deliverIbbPacket(account, packet);
+ } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
+ final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet);
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ } else if (packet.hasChild("query", "jabber:iq:version") && isGet) {
+ final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet);
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ } else if (packet.hasChild("ping", "urn:xmpp:ping") && isGet) {
+ final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ } else if (packet.hasChild("time", "urn:xmpp:time") && isGet) {
+ final IqPacket response;
+ if (mXmppConnectionService.useTorToConnect()) {
+ response = packet.generateResponse(IqPacket.TYPE.ERROR);
+ final Element error = response.addChild("error");
+ error.setAttribute("type", "cancel");
+ error.addChild("not-allowed", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ } else {
+ response = mXmppConnectionService.getIqGenerator().entityTimeResponse(packet);
+ }
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ } else {
+ if (packet.getType() == IqPacket.TYPE.GET || packet.getType() == IqPacket.TYPE.SET) {
+ final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);
+ final Element error = response.addChild("error");
+ error.setAttribute("type", "cancel");
+ error.addChild("feature-not-implemented", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ account.getXmppConnection().sendIqPacket(response, null);
+ }
+ }
+ }
}
diff --git a/src/main/java/de/pixart/messenger/parser/MessageParser.java b/src/main/java/de/pixart/messenger/parser/MessageParser.java
index d506c3fa2..531e29629 100644
--- a/src/main/java/de/pixart/messenger/parser/MessageParser.java
+++ b/src/main/java/de/pixart/messenger/parser/MessageParser.java
@@ -41,396 +41,397 @@ import de.pixart.messenger.xmpp.stanzas.MessagePacket;
public class MessageParser extends AbstractParser implements OnMessagePacketReceived {
- private static final List<String> CLIENTS_SENDING_HTML_IN_OTR = Arrays.asList("Pidgin","Adium","Trillian");
-
- public MessageParser(XmppConnectionService service) {
- super(service);
- }
-
- private boolean extractChatState(Conversation conversation, final MessagePacket packet) {
- ChatState state = ChatState.parse(packet);
- if (state != null && conversation != null) {
- final Account account = conversation.getAccount();
- Jid from = packet.getFrom();
- if (from.toBareJid().equals(account.getJid().toBareJid())) {
- conversation.setOutgoingChatState(state);
- if (state == ChatState.ACTIVE || state == ChatState.COMPOSING) {
- mXmppConnectionService.markRead(conversation);
- activateGracePeriod(account);
- }
- return false;
- } else {
- return conversation.setIncomingChatState(state);
- }
- }
- return false;
- }
-
- private Message parseOtrChat(String body, Jid from, String id, Conversation conversation) {
- String presence;
- if (from.isBareJid()) {
- presence = "";
- } else {
- presence = from.getResourcepart();
- }
- if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) {
- conversation.endOtrIfNeeded();
- }
- if (!conversation.hasValidOtrSession()) {
- conversation.startOtrSession(presence,false);
- } else {
- String foreignPresence = conversation.getOtrSession().getSessionID().getUserID();
- if (!foreignPresence.equals(presence)) {
- conversation.endOtrIfNeeded();
- conversation.startOtrSession(presence, false);
- }
- }
- try {
- conversation.setLastReceivedOtrMessageId(id);
- Session otrSession = conversation.getOtrSession();
- body = otrSession.transformReceiving(body);
- SessionStatus status = otrSession.getSessionStatus();
- if (body == null && status == SessionStatus.ENCRYPTED) {
- mXmppConnectionService.onOtrSessionEstablished(conversation);
- return null;
- } else if (body == null && status == SessionStatus.FINISHED) {
- conversation.resetOtrSession();
- mXmppConnectionService.updateConversationUi();
- return null;
- } else if (body == null || (body.isEmpty())) {
- return null;
- }
- if (body.startsWith(CryptoHelper.FILETRANSFER)) {
- String key = body.substring(CryptoHelper.FILETRANSFER.length());
- conversation.setSymmetricKey(CryptoHelper.hexToBytes(key));
- return null;
- }
- if (clientMightSendHtml(conversation.getAccount(), from)) {
- Log.d(Config.LOGTAG,conversation.getAccount().getJid().toBareJid()+": received OTR message from bad behaving client. escaping HTML…");
- body = Html.fromHtml(body).toString();
- }
-
- final OtrService otrService = conversation.getAccount().getOtrService();
- Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED);
- finishedMessage.setFingerprint(otrService.getFingerprint(otrSession.getRemotePublicKey()));
- conversation.setLastReceivedOtrMessageId(null);
-
- return finishedMessage;
- } catch (Exception e) {
- conversation.resetOtrSession();
- return null;
- }
- }
-
- private static boolean clientMightSendHtml(Account account, Jid from) {
- String resource = from.getResourcepart();
- if (resource == null) {
- return false;
- }
- Presence presence = account.getRoster().getContact(from).getPresences().getPresences().get(resource);
- ServiceDiscoveryResult disco = presence == null ? null : presence.getServiceDiscoveryResult();
- if (disco == null) {
- return false;
- }
- return hasIdentityKnowForSendingHtml(disco.getIdentities());
- }
-
- private static boolean hasIdentityKnowForSendingHtml(List<ServiceDiscoveryResult.Identity> identities) {
- for(ServiceDiscoveryResult.Identity identity : identities) {
- if (identity.getName() != null) {
- if (CLIENTS_SENDING_HTML_IN_OTR.contains(identity.getName())) {
- return true;
- }
- }
- }
- return false;
- }
-
- private Message parseAxolotlChat(Element axolotlMessage, Jid from, Conversation conversation, int status) {
- AxolotlService service = conversation.getAccount().getAxolotlService();
- XmppAxolotlMessage xmppAxolotlMessage;
- try {
- xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlMessage, from.toBareJid());
- } catch (Exception e) {
- Log.d(Config.LOGTAG,conversation.getAccount().getJid().toBareJid()+": invalid omemo message received "+e.getMessage());
- return null;
- }
- XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceivingPayloadMessage(xmppAxolotlMessage);
- if(plaintextMessage != null) {
- 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());
- return finishedMessage;
- } else {
- return null;
- }
- }
-
- private class Invite {
- Jid jid;
- String password;
- Invite(Jid jid, String password) {
- this.jid = jid;
- this.password = password;
- }
-
- public boolean execute(Account account) {
- if (jid != null) {
- Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true);
- if (!conversation.getMucOptions().online()) {
- conversation.getMucOptions().setPassword(password);
- mXmppConnectionService.databaseBackend.updateConversation(conversation);
- mXmppConnectionService.joinMuc(conversation);
- mXmppConnectionService.updateConversationUi();
- }
- return true;
- }
- return false;
- }
- }
-
- private Invite extractInvite(Element message) {
- Element x = message.findChild("x", "http://jabber.org/protocol/muc#user");
- if (x != null) {
- Element invite = x.findChild("invite");
- if (invite != null) {
- Element pw = x.findChild("password");
- return new Invite(message.getAttributeAsJid("from"), pw != null ? pw.getContent(): null);
- }
- } else {
- x = message.findChild("x","jabber:x:conference");
- if (x != null) {
- return new Invite(x.getAttributeAsJid("jid"),x.getAttribute("password"));
- }
- }
- return null;
- }
-
- private static String extractStanzaId(Element packet, Jid by) {
- for(Element child : packet.getChildren()) {
- if (child.getName().equals("stanza-id")
- && Xmlns.STANZA_IDS.equals(child.getNamespace())
- && by.equals(child.getAttributeAsJid("by"))) {
- return child.getAttribute("id");
- }
- }
- return null;
- }
-
- private void parseEvent(final Element event, final Jid from, final Account account) {
- Element items = event.findChild("items");
- String node = items == null ? null : items.getAttribute("node");
- if ("urn:xmpp:avatar:metadata".equals(node)) {
- Avatar avatar = Avatar.parseMetadata(items);
- if (avatar != null) {
- avatar.owner = from.toBareJid();
- if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
- if (account.getJid().toBareJid().equals(from)) {
- if (account.setAvatar(avatar.getFilename())) {
- mXmppConnectionService.databaseBackend.updateAccount(account);
- }
- mXmppConnectionService.getAvatarService().clear(account);
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateAccountUi();
- } else {
- Contact contact = account.getRoster().getContact(from);
- contact.setAvatar(avatar);
- mXmppConnectionService.getAvatarService().clear(contact);
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateRosterUi();
- }
- } else if (mXmppConnectionService.isDataSaverDisabled()) {
- mXmppConnectionService.fetchAvatar(account, avatar);
- }
- }
- } else if ("http://jabber.org/protocol/nick".equals(node)) {
- Element i = items.findChild("item");
- Element nick = i == null ? null : i.findChild("nick", "http://jabber.org/protocol/nick");
- if (nick != null && nick.getContent() != null) {
- Contact contact = account.getRoster().getContact(from);
- contact.setPresenceName(nick.getContent());
- mXmppConnectionService.getAvatarService().clear(account);
- mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateAccountUi();
- }
- } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) {
- Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Received PEP device list update from "+ from + ", processing...");
- Element item = items.findChild("item");
- Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item);
- AxolotlService axolotlService = account.getAxolotlService();
- axolotlService.registerDevices(from, deviceIds);
- mXmppConnectionService.updateAccountUi();
- }
- }
-
- private boolean handleErrorMessage(Account account, MessagePacket packet) {
- if (packet.getType() == MessagePacket.TYPE_ERROR) {
- Jid from = packet.getFrom();
- if (from != null) {
- Message message = mXmppConnectionService.markMessage(account,
- from.toBareJid(),
- packet.getId(),
+ private static final List<String> CLIENTS_SENDING_HTML_IN_OTR = Arrays.asList("Pidgin", "Adium", "Trillian");
+
+ public MessageParser(XmppConnectionService service) {
+ super(service);
+ }
+
+ private boolean extractChatState(Conversation conversation, final MessagePacket packet) {
+ ChatState state = ChatState.parse(packet);
+ if (state != null && conversation != null) {
+ final Account account = conversation.getAccount();
+ Jid from = packet.getFrom();
+ if (from.toBareJid().equals(account.getJid().toBareJid())) {
+ conversation.setOutgoingChatState(state);
+ if (state == ChatState.ACTIVE || state == ChatState.COMPOSING) {
+ mXmppConnectionService.markRead(conversation);
+ activateGracePeriod(account);
+ }
+ return false;
+ } else {
+ return conversation.setIncomingChatState(state);
+ }
+ }
+ return false;
+ }
+
+ private Message parseOtrChat(String body, Jid from, String id, Conversation conversation) {
+ String presence;
+ if (from.isBareJid()) {
+ presence = "";
+ } else {
+ presence = from.getResourcepart();
+ }
+ if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) {
+ conversation.endOtrIfNeeded();
+ }
+ if (!conversation.hasValidOtrSession()) {
+ conversation.startOtrSession(presence, false);
+ } else {
+ String foreignPresence = conversation.getOtrSession().getSessionID().getUserID();
+ if (!foreignPresence.equals(presence)) {
+ conversation.endOtrIfNeeded();
+ conversation.startOtrSession(presence, false);
+ }
+ }
+ try {
+ conversation.setLastReceivedOtrMessageId(id);
+ Session otrSession = conversation.getOtrSession();
+ body = otrSession.transformReceiving(body);
+ SessionStatus status = otrSession.getSessionStatus();
+ if (body == null && status == SessionStatus.ENCRYPTED) {
+ mXmppConnectionService.onOtrSessionEstablished(conversation);
+ return null;
+ } else if (body == null && status == SessionStatus.FINISHED) {
+ conversation.resetOtrSession();
+ mXmppConnectionService.updateConversationUi();
+ return null;
+ } else if (body == null || (body.isEmpty())) {
+ return null;
+ }
+ if (body.startsWith(CryptoHelper.FILETRANSFER)) {
+ String key = body.substring(CryptoHelper.FILETRANSFER.length());
+ conversation.setSymmetricKey(CryptoHelper.hexToBytes(key));
+ return null;
+ }
+ if (clientMightSendHtml(conversation.getAccount(), from)) {
+ Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": received OTR message from bad behaving client. escaping HTML…");
+ body = Html.fromHtml(body).toString();
+ }
+
+ final OtrService otrService = conversation.getAccount().getOtrService();
+ Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED);
+ finishedMessage.setFingerprint(otrService.getFingerprint(otrSession.getRemotePublicKey()));
+ conversation.setLastReceivedOtrMessageId(null);
+
+ return finishedMessage;
+ } catch (Exception e) {
+ conversation.resetOtrSession();
+ return null;
+ }
+ }
+
+ private static boolean clientMightSendHtml(Account account, Jid from) {
+ String resource = from.getResourcepart();
+ if (resource == null) {
+ return false;
+ }
+ Presence presence = account.getRoster().getContact(from).getPresences().getPresences().get(resource);
+ ServiceDiscoveryResult disco = presence == null ? null : presence.getServiceDiscoveryResult();
+ if (disco == null) {
+ return false;
+ }
+ return hasIdentityKnowForSendingHtml(disco.getIdentities());
+ }
+
+ private static boolean hasIdentityKnowForSendingHtml(List<ServiceDiscoveryResult.Identity> identities) {
+ for (ServiceDiscoveryResult.Identity identity : identities) {
+ if (identity.getName() != null) {
+ if (CLIENTS_SENDING_HTML_IN_OTR.contains(identity.getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private Message parseAxolotlChat(Element axolotlMessage, Jid from, Conversation conversation, int status) {
+ AxolotlService service = conversation.getAccount().getAxolotlService();
+ XmppAxolotlMessage xmppAxolotlMessage;
+ try {
+ xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlMessage, from.toBareJid());
+ } catch (Exception e) {
+ Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": invalid omemo message received " + e.getMessage());
+ return null;
+ }
+ XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceivingPayloadMessage(xmppAxolotlMessage);
+ if (plaintextMessage != null) {
+ 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());
+ return finishedMessage;
+ } else {
+ return null;
+ }
+ }
+
+ private class Invite {
+ Jid jid;
+ String password;
+
+ Invite(Jid jid, String password) {
+ this.jid = jid;
+ this.password = password;
+ }
+
+ public boolean execute(Account account) {
+ if (jid != null) {
+ Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true);
+ if (!conversation.getMucOptions().online()) {
+ conversation.getMucOptions().setPassword(password);
+ mXmppConnectionService.databaseBackend.updateConversation(conversation);
+ mXmppConnectionService.joinMuc(conversation);
+ mXmppConnectionService.updateConversationUi();
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private Invite extractInvite(Element message) {
+ Element x = message.findChild("x", "http://jabber.org/protocol/muc#user");
+ if (x != null) {
+ Element invite = x.findChild("invite");
+ if (invite != null) {
+ Element pw = x.findChild("password");
+ return new Invite(message.getAttributeAsJid("from"), pw != null ? pw.getContent() : null);
+ }
+ } else {
+ x = message.findChild("x", "jabber:x:conference");
+ if (x != null) {
+ return new Invite(x.getAttributeAsJid("jid"), x.getAttribute("password"));
+ }
+ }
+ return null;
+ }
+
+ private static String extractStanzaId(Element packet, Jid by) {
+ for (Element child : packet.getChildren()) {
+ if (child.getName().equals("stanza-id")
+ && Xmlns.STANZA_IDS.equals(child.getNamespace())
+ && by.equals(child.getAttributeAsJid("by"))) {
+ return child.getAttribute("id");
+ }
+ }
+ return null;
+ }
+
+ private void parseEvent(final Element event, final Jid from, final Account account) {
+ Element items = event.findChild("items");
+ String node = items == null ? null : items.getAttribute("node");
+ if ("urn:xmpp:avatar:metadata".equals(node)) {
+ Avatar avatar = Avatar.parseMetadata(items);
+ if (avatar != null) {
+ avatar.owner = from.toBareJid();
+ if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
+ if (account.getJid().toBareJid().equals(from)) {
+ if (account.setAvatar(avatar.getFilename())) {
+ mXmppConnectionService.databaseBackend.updateAccount(account);
+ }
+ mXmppConnectionService.getAvatarService().clear(account);
+ mXmppConnectionService.updateConversationUi();
+ mXmppConnectionService.updateAccountUi();
+ } else {
+ Contact contact = account.getRoster().getContact(from);
+ contact.setAvatar(avatar);
+ mXmppConnectionService.getAvatarService().clear(contact);
+ mXmppConnectionService.updateConversationUi();
+ mXmppConnectionService.updateRosterUi();
+ }
+ } else if (mXmppConnectionService.isDataSaverDisabled()) {
+ mXmppConnectionService.fetchAvatar(account, avatar);
+ }
+ }
+ } else if ("http://jabber.org/protocol/nick".equals(node)) {
+ Element i = items.findChild("item");
+ Element nick = i == null ? null : i.findChild("nick", "http://jabber.org/protocol/nick");
+ if (nick != null && nick.getContent() != null) {
+ Contact contact = account.getRoster().getContact(from);
+ contact.setPresenceName(nick.getContent());
+ mXmppConnectionService.getAvatarService().clear(account);
+ mXmppConnectionService.updateConversationUi();
+ mXmppConnectionService.updateAccountUi();
+ }
+ } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) {
+ Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received PEP device list update from " + from + ", processing...");
+ Element item = items.findChild("item");
+ Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item);
+ AxolotlService axolotlService = account.getAxolotlService();
+ axolotlService.registerDevices(from, deviceIds);
+ mXmppConnectionService.updateAccountUi();
+ }
+ }
+
+ private boolean handleErrorMessage(Account account, MessagePacket packet) {
+ if (packet.getType() == MessagePacket.TYPE_ERROR) {
+ Jid from = packet.getFrom();
+ if (from != null) {
+ Message message = mXmppConnectionService.markMessage(account,
+ from.toBareJid(),
+ packet.getId(),
Message.STATUS_SEND_FAILED,
extractErrorMessage(packet));
if (message != null) {
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
message.getConversation().endOtrIfNeeded();
}
- }
- }
- return true;
- }
- return false;
- }
-
- @Override
- public void onMessagePacketReceived(Account account, MessagePacket original) {
- if (handleErrorMessage(account, original)) {
- return;
- }
- final MessagePacket packet;
- Long timestamp = null;
- final boolean isForwarded;
- boolean isCarbon = false;
- String serverMsgId = null;
- final Element fin = original.findChild("fin", "urn:xmpp:mam:0");
- if (fin != null) {
- mXmppConnectionService.getMessageArchiveService().processFin(fin,original.getFrom());
- return;
- }
- final Element result = original.findChild("result","urn:xmpp:mam:0");
- final MessageArchiveService.Query query = result == null ? null : mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid"));
- if (query != null && query.validFrom(original.getFrom())) {
- Pair<MessagePacket, Long> f = original.getForwardedMessagePacket("result", "urn:xmpp:mam:0");
- if (f == null) {
- return;
- }
- timestamp = f.second;
- packet = f.first;
- isForwarded = true;
- serverMsgId = result.getAttribute("id");
- query.incrementMessageCount();
- } else if (query != null) {
- Log.d(Config.LOGTAG,account.getJid().toBareJid()+": received mam result from invalid sender");
- return;
- } else if (original.fromServer(account)) {
- Pair<MessagePacket, Long> f;
- f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2");
- f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f;
- packet = f != null ? f.first : original;
- if (handleErrorMessage(account, packet)) {
- return;
- }
- timestamp = f != null ? f.second : null;
- isCarbon = f != null;
- isForwarded = isCarbon;
- } else {
- packet = original;
- isForwarded = false;
- }
-
- if (timestamp == null) {
- timestamp = AbstractParser.parseTimestamp(original,AbstractParser.parseTimestamp(packet));
- }
- final String body = packet.getBody();
- final Element mucUserElement = packet.findChild("x", "http://jabber.org/protocol/muc#user");
- final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
- final Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0");
- final Element oob = packet.findChild("x", "jabber:x:oob");
- final boolean isOob = oob!= null && body != null && body.equals(oob.findChildContent("url"));
- final String replacementId = replaceElement == null ? null : replaceElement.getAttribute("id");
- final Element axolotlEncrypted = packet.findChild(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
- int status;
- final Jid counterpart;
- final Jid to = packet.getTo();
- final Jid from = packet.getFrom();
- final String remoteMsgId = packet.getId();
- boolean notify = false;
-
- if (from == null) {
- Log.d(Config.LOGTAG,"no from in: "+packet.toString());
- return;
- }
-
- boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT;
- boolean isProperlyAddressed = (to != null ) && (!to.isBareJid() || account.countPresences() == 0);
- boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status");
- if (packet.fromAccount(account)) {
- status = Message.STATUS_SEND;
- counterpart = to != null ? to : account.getJid();
- } else {
- status = Message.STATUS_RECEIVED;
- counterpart = from;
- }
-
- Invite invite = extractInvite(packet);
- if (invite != null && invite.execute(account)) {
- return;
- }
-
- if (!isTypeGroupChat
- && query == null
- && extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), packet)) {
- mXmppConnectionService.updateConversationUi();
- }
-
- if ((body != null || pgpEncrypted != null || axolotlEncrypted != null) && !isMucStatusMessage) {
- Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat, query);
- final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
- if (isTypeGroupChat) {
- if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
- status = Message.STATUS_SEND_RECEIVED;
- isCarbon = true; //not really carbon but received from another resource
- if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) {
- return;
- } else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) {
- Message message = conversation.findSentMessageWithBody(packet.getBody());
- if (message != null) {
- mXmppConnectionService.markMessage(message, status);
- return;
- }
- }
- } else {
- status = Message.STATUS_RECEIVED;
- }
- }
- final Message message;
- if (body != null && body.startsWith("?OTR") && Config.supportOtr()) {
- if (!isForwarded && !isTypeGroupChat && isProperlyAddressed && !conversationMultiMode) {
- message = parseOtrChat(body, from, remoteMsgId, conversation);
- if (message == null) {
- return;
- }
- } else {
- Log.d(Config.LOGTAG,account.getJid().toBareJid()+": ignoring OTR message from "+from+" isForwarded="+Boolean.toString(isForwarded)+", isProperlyAddressed="+Boolean.valueOf(isProperlyAddressed));
- message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
- }
- } else if (pgpEncrypted != null && Config.supportOpenPgp()) {
- message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status);
- } else if (axolotlEncrypted != null && Config.supportOmemo()) {
- Jid origin;
- if (conversationMultiMode) {
- final Jid fallback = conversation.getMucOptions().getTrueCounterpart(counterpart);
- origin = getTrueCounterpart(query != null ? mucUserElement : null, fallback);
- if (origin == null) {
- Log.d(Config.LOGTAG,"axolotl message in non anonymous conference received");
- return;
- }
- } else {
- origin = from;
- }
- message = parseAxolotlChat(axolotlEncrypted, origin, conversation, status);
- if (message == null) {
- return;
- }
- if (conversationMultiMode) {
- message.setTrueCounterpart(origin);
- }
- } else {
- message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
- }
-
- if (serverMsgId == null) {
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onMessagePacketReceived(Account account, MessagePacket original) {
+ if (handleErrorMessage(account, original)) {
+ return;
+ }
+ final MessagePacket packet;
+ Long timestamp = null;
+ final boolean isForwarded;
+ boolean isCarbon = false;
+ String serverMsgId = null;
+ final Element fin = original.findChild("fin", "urn:xmpp:mam:0");
+ if (fin != null) {
+ mXmppConnectionService.getMessageArchiveService().processFin(fin, original.getFrom());
+ return;
+ }
+ final Element result = original.findChild("result", "urn:xmpp:mam:0");
+ final MessageArchiveService.Query query = result == null ? null : mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid"));
+ if (query != null && query.validFrom(original.getFrom())) {
+ Pair<MessagePacket, Long> f = original.getForwardedMessagePacket("result", "urn:xmpp:mam:0");
+ if (f == null) {
+ return;
+ }
+ timestamp = f.second;
+ packet = f.first;
+ isForwarded = true;
+ serverMsgId = result.getAttribute("id");
+ query.incrementMessageCount();
+ } else if (query != null) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": received mam result from invalid sender");
+ return;
+ } else if (original.fromServer(account)) {
+ Pair<MessagePacket, Long> f;
+ f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2");
+ f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f;
+ packet = f != null ? f.first : original;
+ if (handleErrorMessage(account, packet)) {
+ return;
+ }
+ timestamp = f != null ? f.second : null;
+ isCarbon = f != null;
+ isForwarded = isCarbon;
+ } else {
+ packet = original;
+ isForwarded = false;
+ }
+
+ if (timestamp == null) {
+ timestamp = AbstractParser.parseTimestamp(original, AbstractParser.parseTimestamp(packet));
+ }
+ final String body = packet.getBody();
+ final Element mucUserElement = packet.findChild("x", "http://jabber.org/protocol/muc#user");
+ final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
+ final Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0");
+ final Element oob = packet.findChild("x", "jabber:x:oob");
+ final boolean isOob = oob != null && body != null && body.equals(oob.findChildContent("url"));
+ final String replacementId = replaceElement == null ? null : replaceElement.getAttribute("id");
+ final Element axolotlEncrypted = packet.findChild(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
+ int status;
+ final Jid counterpart;
+ final Jid to = packet.getTo();
+ final Jid from = packet.getFrom();
+ final String remoteMsgId = packet.getId();
+ boolean notify = false;
+
+ if (from == null) {
+ Log.d(Config.LOGTAG, "no from in: " + packet.toString());
+ return;
+ }
+
+ boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT;
+ boolean isProperlyAddressed = (to != null) && (!to.isBareJid() || account.countPresences() == 0);
+ boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status");
+ if (packet.fromAccount(account)) {
+ status = Message.STATUS_SEND;
+ counterpart = to != null ? to : account.getJid();
+ } else {
+ status = Message.STATUS_RECEIVED;
+ counterpart = from;
+ }
+
+ Invite invite = extractInvite(packet);
+ if (invite != null && invite.execute(account)) {
+ return;
+ }
+
+ if (!isTypeGroupChat
+ && query == null
+ && extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), packet)) {
+ mXmppConnectionService.updateConversationUi();
+ }
+
+ if ((body != null || pgpEncrypted != null || axolotlEncrypted != null) && !isMucStatusMessage) {
+ Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat, query);
+ final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
+ if (isTypeGroupChat) {
+ if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
+ status = Message.STATUS_SEND_RECEIVED;
+ isCarbon = true; //not really carbon but received from another resource
+ if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) {
+ return;
+ } else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) {
+ Message message = conversation.findSentMessageWithBody(packet.getBody());
+ if (message != null) {
+ mXmppConnectionService.markMessage(message, status);
+ return;
+ }
+ }
+ } else {
+ status = Message.STATUS_RECEIVED;
+ }
+ }
+ final Message message;
+ if (body != null && body.startsWith("?OTR") && Config.supportOtr()) {
+ if (!isForwarded && !isTypeGroupChat && isProperlyAddressed && !conversationMultiMode) {
+ message = parseOtrChat(body, from, remoteMsgId, conversation);
+ if (message == null) {
+ return;
+ }
+ } else {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ignoring OTR message from " + from + " isForwarded=" + Boolean.toString(isForwarded) + ", isProperlyAddressed=" + Boolean.valueOf(isProperlyAddressed));
+ message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
+ }
+ } else if (pgpEncrypted != null && Config.supportOpenPgp()) {
+ message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status);
+ } else if (axolotlEncrypted != null && Config.supportOmemo()) {
+ Jid origin;
+ if (conversationMultiMode) {
+ final Jid fallback = conversation.getMucOptions().getTrueCounterpart(counterpart);
+ origin = getTrueCounterpart(query != null ? mucUserElement : null, fallback);
+ if (origin == null) {
+ Log.d(Config.LOGTAG, "axolotl message in non anonymous conference received");
+ return;
+ }
+ } else {
+ origin = from;
+ }
+ message = parseAxolotlChat(axolotlEncrypted, origin, conversation, status);
+ if (message == null) {
+ return;
+ }
+ if (conversationMultiMode) {
+ message.setTrueCounterpart(origin);
+ }
+ } else {
+ message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
+ }
+
+ if (serverMsgId == null) {
final Jid by;
final boolean safeToExtract;
if (isTypeGroupChat) {
@@ -443,154 +444,154 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
if (safeToExtract) {
serverMsgId = extractStanzaId(packet, by);
}
- }
-
- message.setCounterpart(counterpart);
- message.setRemoteMsgId(remoteMsgId);
- message.setServerMsgId(serverMsgId);
- message.setCarbon(isCarbon);
- message.setTime(timestamp);
- message.setOob(isOob);
- message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
- if (conversationMultiMode) {
- final Jid fallback = conversation.getMucOptions().getTrueCounterpart(counterpart);
- Jid trueCounterpart;
- if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
- trueCounterpart = message.getTrueCounterpart();
- } else if (Config.PARSE_REAL_JID_FROM_MUC_MAM) {
- trueCounterpart = getTrueCounterpart(query != null ? mucUserElement : null, fallback);
- } else {
- trueCounterpart = fallback;
- }
- if (trueCounterpart != null && trueCounterpart.toBareJid().equals(account.getJid().toBareJid())) {
- status = isTypeGroupChat ? Message.STATUS_SEND_RECEIVED : Message.STATUS_SEND;
- }
- message.setStatus(status);
- message.setTrueCounterpart(trueCounterpart);
- if (!isTypeGroupChat) {
- message.setType(Message.TYPE_PRIVATE);
- }
- } else {
- updateLastseen(account, from);
- }
-
- if (replacementId != null && mXmppConnectionService.allowMessageCorrection()) {
- 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
- && replacedMessage.getTrueCounterpart().equals(message.getTrueCounterpart());
- if (fingerprintsMatch && (trueCountersMatch || !conversationMultiMode)) {
- Log.d(Config.LOGTAG, "replaced message '" + replacedMessage.getBody() + "' with '" + message.getBody() + "'");
- synchronized (replacedMessage) {
- final String uuid = replacedMessage.getUuid();
- replacedMessage.setUuid(UUID.randomUUID().toString());
- replacedMessage.setBody(message.getBody());
- replacedMessage.setEdited(replacedMessage.getRemoteMsgId());
- replacedMessage.setRemoteMsgId(remoteMsgId);
- replacedMessage.setEncryption(message.getEncryption());
- if (replacedMessage.getStatus() == Message.STATUS_RECEIVED) {
- replacedMessage.markUnread();
- }
- mXmppConnectionService.updateMessage(replacedMessage, uuid);
- mXmppConnectionService.getNotificationService().updateNotification(false);
- if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded && !isTypeGroupChat) {
- sendMessageReceipts(account, packet);
- }
- if (replacedMessage.getEncryption() == Message.ENCRYPTION_PGP) {
- conversation.getAccount().getPgpDecryptionService().discard(replacedMessage);
- conversation.getAccount().getPgpDecryptionService().decrypt(replacedMessage, false);
- }
- }
- return;
- } else {
- Log.d(Config.LOGTAG,account.getJid().toBareJid()+": received message correction but verification didn't check out");
- }
- }
- }
-
- boolean checkForDuplicates = query != null
- || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay"))
- || message.getType() == Message.TYPE_PRIVATE;
- if (checkForDuplicates && conversation.hasDuplicateMessage(message)) {
- Log.d(Config.LOGTAG,"skipping duplicate message from "+message.getCounterpart().toString()+" "+message.getBody());
- return;
- }
-
- if (query != null && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {
- conversation.prepend(message);
- } else {
- conversation.add(message);
- }
-
- if (query == null || query.getWith() == null) { //either no mam or catchup
- if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) {
- mXmppConnectionService.markRead(conversation);
- if (query == null) {
- activateGracePeriod(account);
- }
- } else {
- message.markUnread();
- notify = true;
- }
- }
-
- if (message.getEncryption() == Message.ENCRYPTION_PGP) {
- notify = conversation.getAccount().getPgpDecryptionService().decrypt(message, notify);
- }
-
- if (query == null) {
- mXmppConnectionService.updateConversationUi();
- }
+ }
+
+ message.setCounterpart(counterpart);
+ message.setRemoteMsgId(remoteMsgId);
+ message.setServerMsgId(serverMsgId);
+ message.setCarbon(isCarbon);
+ message.setTime(timestamp);
+ message.setOob(isOob);
+ message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
+ if (conversationMultiMode) {
+ final Jid fallback = conversation.getMucOptions().getTrueCounterpart(counterpart);
+ Jid trueCounterpart;
+ if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
+ trueCounterpart = message.getTrueCounterpart();
+ } else if (Config.PARSE_REAL_JID_FROM_MUC_MAM) {
+ trueCounterpart = getTrueCounterpart(query != null ? mucUserElement : null, fallback);
+ } else {
+ trueCounterpart = fallback;
+ }
+ if (trueCounterpart != null && trueCounterpart.toBareJid().equals(account.getJid().toBareJid())) {
+ status = isTypeGroupChat ? Message.STATUS_SEND_RECEIVED : Message.STATUS_SEND;
+ }
+ message.setStatus(status);
+ message.setTrueCounterpart(trueCounterpart);
+ if (!isTypeGroupChat) {
+ message.setType(Message.TYPE_PRIVATE);
+ }
+ } else {
+ updateLastseen(account, from);
+ }
+
+ if (replacementId != null && mXmppConnectionService.allowMessageCorrection()) {
+ 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
+ && replacedMessage.getTrueCounterpart().equals(message.getTrueCounterpart());
+ if (fingerprintsMatch && (trueCountersMatch || !conversationMultiMode)) {
+ Log.d(Config.LOGTAG, "replaced message '" + replacedMessage.getBody() + "' with '" + message.getBody() + "'");
+ synchronized (replacedMessage) {
+ final String uuid = replacedMessage.getUuid();
+ replacedMessage.setUuid(UUID.randomUUID().toString());
+ replacedMessage.setBody(message.getBody());
+ replacedMessage.setEdited(replacedMessage.getRemoteMsgId());
+ replacedMessage.setRemoteMsgId(remoteMsgId);
+ replacedMessage.setEncryption(message.getEncryption());
+ if (replacedMessage.getStatus() == Message.STATUS_RECEIVED) {
+ replacedMessage.markUnread();
+ }
+ mXmppConnectionService.updateMessage(replacedMessage, uuid);
+ mXmppConnectionService.getNotificationService().updateNotification(false);
+ if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded && !isTypeGroupChat) {
+ sendMessageReceipts(account, packet);
+ }
+ if (replacedMessage.getEncryption() == Message.ENCRYPTION_PGP) {
+ conversation.getAccount().getPgpDecryptionService().discard(replacedMessage);
+ conversation.getAccount().getPgpDecryptionService().decrypt(replacedMessage, false);
+ }
+ }
+ return;
+ } else {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": received message correction but verification didn't check out");
+ }
+ }
+ }
+
+ boolean checkForDuplicates = query != null
+ || (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay"))
+ || message.getType() == Message.TYPE_PRIVATE;
+ if (checkForDuplicates && conversation.hasDuplicateMessage(message)) {
+ Log.d(Config.LOGTAG, "skipping duplicate message from " + message.getCounterpart().toString() + " " + message.getBody());
+ return;
+ }
+
+ if (query != null && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {
+ conversation.prepend(message);
+ } else {
+ conversation.add(message);
+ }
+
+ if (query == null || query.getWith() == null) { //either no mam or catchup
+ if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) {
+ mXmppConnectionService.markRead(conversation);
+ if (query == null) {
+ activateGracePeriod(account);
+ }
+ } else {
+ message.markUnread();
+ notify = true;
+ }
+ }
+
+ if (message.getEncryption() == Message.ENCRYPTION_PGP) {
+ notify = conversation.getAccount().getPgpDecryptionService().decrypt(message, notify);
+ }
+
+ if (query == null) {
+ mXmppConnectionService.updateConversationUi();
+ }
if (mXmppConnectionService.confirmMessages() && message.trusted() && remoteMsgId != null && !isForwarded && !isTypeGroupChat) {
- sendMessageReceipts(account, packet);
- }
-
- if (message.getStatus() == Message.STATUS_RECEIVED
- && conversation.getOtrSession() != null
- && !conversation.getOtrSession().getSessionID().getUserID()
- .equals(message.getCounterpart().getResourcepart())) {
- conversation.endOtrIfNeeded();
- }
-
- if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) {
- mXmppConnectionService.databaseBackend.createMessage(message);
- }
- final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
- if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) {
- manager.createNewDownloadConnection(message);
- } else if (notify) {
- if (query == null) {
- mXmppConnectionService.getNotificationService().push(message);
- } else if (query.getWith() == null) { // mam catchup
- mXmppConnectionService.getNotificationService().pushFromBacklog(message);
- }
- }
- } else if (!packet.hasChild("body")){ //no body
- Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
- if (isTypeGroupChat) {
- if (packet.hasChild("subject")) {
- if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
- conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0);
- String subject = packet.findChildContent("subject");
- conversation.getMucOptions().setSubject(subject);
- final Bookmark bookmark = conversation.getBookmark();
- if (bookmark != null && bookmark.getBookmarkName() == null) {
- if (bookmark.setBookmarkName(subject)) {
- mXmppConnectionService.pushBookmarks(account);
- }
- }
- mXmppConnectionService.updateConversationUi();
- return;
- }
- }
- }
- if (conversation != null && mucUserElement != null && from.isBareJid()) {
+ sendMessageReceipts(account, packet);
+ }
+
+ if (message.getStatus() == Message.STATUS_RECEIVED
+ && conversation.getOtrSession() != null
+ && !conversation.getOtrSession().getSessionID().getUserID()
+ .equals(message.getCounterpart().getResourcepart())) {
+ conversation.endOtrIfNeeded();
+ }
+
+ if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) {
+ mXmppConnectionService.databaseBackend.createMessage(message);
+ }
+ final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
+ if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) {
+ manager.createNewDownloadConnection(message);
+ } else if (notify) {
+ if (query == null) {
+ mXmppConnectionService.getNotificationService().push(message);
+ } else if (query.getWith() == null) { // mam catchup
+ mXmppConnectionService.getNotificationService().pushFromBacklog(message);
+ }
+ }
+ } else if (!packet.hasChild("body")) { //no body
+ Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
+ if (isTypeGroupChat) {
+ if (packet.hasChild("subject")) {
+ if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
+ conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0);
+ String subject = packet.findChildContent("subject");
+ conversation.getMucOptions().setSubject(subject);
+ final Bookmark bookmark = conversation.getBookmark();
+ if (bookmark != null && bookmark.getBookmarkName() == null) {
+ if (bookmark.setBookmarkName(subject)) {
+ mXmppConnectionService.pushBookmarks(account);
+ }
+ }
+ mXmppConnectionService.updateConversationUi();
+ return;
+ }
+ }
+ }
+ if (conversation != null && mucUserElement != null && from.isBareJid()) {
for (Element child : mucUserElement.getChildren()) {
if ("status".equals(child.getName())) {
try {
@@ -598,92 +599,91 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
if ((code >= 170 && code <= 174) || (code >= 102 && code <= 104)) {
mXmppConnectionService.fetchConferenceConfiguration(conversation);
break;
- }
+ }
} catch (Exception e) {
//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().toBareJid());
+ MucOptions.User user = AbstractParser.parseItem(conversation, child);
+ Log.d(Config.LOGTAG, account.getJid() + ": changing affiliation for " + user.getRealJid() + " to " + user.getAffiliation() + " in " + conversation.getJid().toBareJid());
if (!user.realJidMatchesAccount()) {
conversation.getMucOptions().updateUser(user);
mXmppConnectionService.getAvatarService().clear(conversation);
mXmppConnectionService.updateMucRosterUi();
mXmppConnectionService.updateConversationUi();
- }
- }
- }
- }
- }
-
-
-
- Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
- if (received == null) {
- received = packet.findChild("received", "urn:xmpp:receipts");
- }
- if (received != null && !packet.fromAccount(account)) {
- mXmppConnectionService.markMessage(account, from.toBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED);
- }
- Element displayed = packet.findChild("displayed", "urn:xmpp:chat-markers:0");
- if (displayed != null) {
- if (packet.fromAccount(account)) {
- Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid());
- if (conversation != null) {
- mXmppConnectionService.markRead(conversation);
- }
- } else {
- final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED);
- Message message = displayedMessage == null ? null : displayedMessage.prev();
- while (message != null
- && message.getStatus() == Message.STATUS_SEND_RECEIVED
- && message.getTimeSent() < displayedMessage.getTimeSent()) {
- mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
- message = message.prev();
- }
- }
- }
-
- Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event");
- if (event != null) {
- parseEvent(event, from, account);
- }
-
- String nick = packet.findChildContent("nick", "http://jabber.org/protocol/nick");
- if (nick != null) {
- Contact contact = account.getRoster().getContact(from);
- contact.setPresenceName(nick);
- }
- }
-
- private static Jid getTrueCounterpart(Element mucUserElement, Jid fallback) {
- final Element item = mucUserElement == null ? null : mucUserElement.findChild("item");
- Jid result = item == null ? null : item.getAttributeAsJid("jid");
- return result != null ? result : fallback;
- }
-
- private void sendMessageReceipts(Account account, MessagePacket packet) {
- ArrayList<String> receiptsNamespaces = new ArrayList<>();
- if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) {
- receiptsNamespaces.add("urn:xmpp:chat-markers:0");
- }
- if (packet.hasChild("request", "urn:xmpp:receipts")) {
- receiptsNamespaces.add("urn:xmpp:receipts");
- }
- if (receiptsNamespaces.size() > 0) {
- MessagePacket receipt = mXmppConnectionService.getMessageGenerator().received(account,
- packet,
- receiptsNamespaces,
- packet.getType());
- mXmppConnectionService.sendMessagePacket(account, receipt);
- }
- }
-
- private static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
-
- private void activateGracePeriod(Account account) {
- long duration = mXmppConnectionService.getPreferences().getLong("race_period_length", 144) * 1000;
- Log.d(Config.LOGTAG,account.getJid().toBareJid()+": activating grace period till "+TIME_FORMAT.format(new Date(System.currentTimeMillis() + duration)));
- account.activateGracePeriod(duration);
- }
+ }
+ }
+ }
+ }
+ }
+
+
+ Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
+ if (received == null) {
+ received = packet.findChild("received", "urn:xmpp:receipts");
+ }
+ if (received != null && !packet.fromAccount(account)) {
+ mXmppConnectionService.markMessage(account, from.toBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED);
+ }
+ Element displayed = packet.findChild("displayed", "urn:xmpp:chat-markers:0");
+ if (displayed != null) {
+ if (packet.fromAccount(account)) {
+ Conversation conversation = mXmppConnectionService.find(account, counterpart.toBareJid());
+ if (conversation != null) {
+ mXmppConnectionService.markRead(conversation);
+ }
+ } else {
+ final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED);
+ Message message = displayedMessage == null ? null : displayedMessage.prev();
+ while (message != null
+ && message.getStatus() == Message.STATUS_SEND_RECEIVED
+ && message.getTimeSent() < displayedMessage.getTimeSent()) {
+ mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
+ message = message.prev();
+ }
+ }
+ }
+
+ Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event");
+ if (event != null) {
+ parseEvent(event, from, account);
+ }
+
+ String nick = packet.findChildContent("nick", "http://jabber.org/protocol/nick");
+ if (nick != null) {
+ Contact contact = account.getRoster().getContact(from);
+ contact.setPresenceName(nick);
+ }
+ }
+
+ private static Jid getTrueCounterpart(Element mucUserElement, Jid fallback) {
+ final Element item = mucUserElement == null ? null : mucUserElement.findChild("item");
+ Jid result = item == null ? null : item.getAttributeAsJid("jid");
+ return result != null ? result : fallback;
+ }
+
+ private void sendMessageReceipts(Account account, MessagePacket packet) {
+ ArrayList<String> receiptsNamespaces = new ArrayList<>();
+ if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) {
+ receiptsNamespaces.add("urn:xmpp:chat-markers:0");
+ }
+ if (packet.hasChild("request", "urn:xmpp:receipts")) {
+ receiptsNamespaces.add("urn:xmpp:receipts");
+ }
+ if (receiptsNamespaces.size() > 0) {
+ MessagePacket receipt = mXmppConnectionService.getMessageGenerator().received(account,
+ packet,
+ receiptsNamespaces,
+ packet.getType());
+ mXmppConnectionService.sendMessagePacket(account, receipt);
+ }
+ }
+
+ private static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
+
+ private void activateGracePeriod(Account account) {
+ long duration = mXmppConnectionService.getPreferences().getLong("race_period_length", 144) * 1000;
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": activating grace period till " + TIME_FORMAT.format(new Date(System.currentTimeMillis() + duration)));
+ account.activateGracePeriod(duration);
+ }
}
diff --git a/src/main/java/de/pixart/messenger/parser/PresenceParser.java b/src/main/java/de/pixart/messenger/parser/PresenceParser.java
index 50f13150b..9ba45b201 100644
--- a/src/main/java/de/pixart/messenger/parser/PresenceParser.java
+++ b/src/main/java/de/pixart/messenger/parser/PresenceParser.java
@@ -24,170 +24,170 @@ import de.pixart.messenger.xmpp.pep.Avatar;
import de.pixart.messenger.xmpp.stanzas.PresencePacket;
public class PresenceParser extends AbstractParser implements
- OnPresencePacketReceived {
+ OnPresencePacketReceived {
- public PresenceParser(XmppConnectionService service) {
- super(service);
- }
+ public PresenceParser(XmppConnectionService service) {
+ super(service);
+ }
- public void parseConferencePresence(PresencePacket packet, Account account) {
- final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().toBareJid());
- if (conversation != null) {
- final MucOptions mucOptions = conversation.getMucOptions();
- boolean before = mucOptions.online();
- int count = mucOptions.getUserCount();
- final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
- processConferencePresence(packet, conversation);
- final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
- if (!tileUserAfter.equals(tileUserBefore)) {
- mXmppConnectionService.getAvatarService().clear(mucOptions);
- }
- if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
- mXmppConnectionService.updateConversationUi();
- } else if (mucOptions.online()) {
- mXmppConnectionService.updateMucRosterUi();
- }
- }
- }
+ public void parseConferencePresence(PresencePacket packet, Account account) {
+ final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().toBareJid());
+ if (conversation != null) {
+ final MucOptions mucOptions = conversation.getMucOptions();
+ boolean before = mucOptions.online();
+ int count = mucOptions.getUserCount();
+ final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
+ processConferencePresence(packet, conversation);
+ final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
+ if (!tileUserAfter.equals(tileUserBefore)) {
+ mXmppConnectionService.getAvatarService().clear(mucOptions);
+ }
+ if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
+ mXmppConnectionService.updateConversationUi();
+ } else if (mucOptions.online()) {
+ mXmppConnectionService.updateMucRosterUi();
+ }
+ }
+ }
private void processConferencePresence(PresencePacket packet, Conversation conversation) {
MucOptions mucOptions = conversation.getMucOptions();
- final Jid from = packet.getFrom();
- if (!from.isBareJid()) {
- final String type = packet.getAttribute("type");
- final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user");
- Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
- final List<String> codes = getStatusCodes(x);
- if (type == null) {
- if (x != null) {
- Element item = x.findChild("item");
- if (item != null && !from.isBareJid()) {
- mucOptions.setError(MucOptions.Error.NONE);
+ final Jid from = packet.getFrom();
+ if (!from.isBareJid()) {
+ final String type = packet.getAttribute("type");
+ final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user");
+ Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
+ final List<String> codes = getStatusCodes(x);
+ if (type == null) {
+ if (x != null) {
+ Element item = x.findChild("item");
+ if (item != null && !from.isBareJid()) {
+ mucOptions.setError(MucOptions.Error.NONE);
MucOptions.User user = parseItem(conversation, item, from);
- if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) {
- mucOptions.setOnline();
- mucOptions.setSelf(user);
- if (mucOptions.mNickChangingInProgress) {
- if (mucOptions.onRenameListener != null) {
- mucOptions.onRenameListener.onSuccess();
- }
- mucOptions.mNickChangingInProgress = false;
- }
- } else {
- mucOptions.updateUser(user);
- }
- if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) {
- Log.d(Config.LOGTAG,mucOptions.getAccount().getJid().toBareJid()
- +": room '"
- +mucOptions.getConversation().getJid().toBareJid()
- +"' created. pushing default configuration");
- mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(),
- IqGenerator.defaultRoomConfiguration(),
- null);
- }
- if (mXmppConnectionService.getPgpEngine() != null) {
- Element signed = packet.findChild("x", "jabber:x:signed");
- if (signed != null) {
- Element status = packet.findChild("status");
- String msg = status == null ? "" : status.getContent();
- long keyId = mXmppConnectionService.getPgpEngine().fetchKeyId(mucOptions.getAccount(), msg, signed.getContent());
- if (keyId != 0) {
- user.setPgpKeyId(keyId);
- }
- }
- }
- if (avatar != null) {
- avatar.owner = from;
- if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
- if (user.setAvatar(avatar)) {
- mXmppConnectionService.getAvatarService().clear(user);
- }
- } else if (mXmppConnectionService.isDataSaverDisabled()) {
- mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar);
- }
- }
- }
- }
- } else if (type.equals("unavailable")) {
- if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) ||
- packet.getFrom().equals(mucOptions.getConversation().getJid())) {
- if (codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) {
- mucOptions.mNickChangingInProgress = true;
- } else if (codes.contains(MucOptions.STATUS_CODE_KICKED)) {
- mucOptions.setError(MucOptions.Error.KICKED);
- } else if (codes.contains(MucOptions.STATUS_CODE_BANNED)) {
- mucOptions.setError(MucOptions.Error.BANNED);
- } else if (codes.contains(MucOptions.STATUS_CODE_LOST_MEMBERSHIP)) {
- mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
- } else if (codes.contains(MucOptions.STATUS_CODE_AFFILIATION_CHANGE)) {
- mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
- } else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN)) {
- mucOptions.setError(MucOptions.Error.SHUTDOWN);
- } else {
- mucOptions.setError(MucOptions.Error.UNKNOWN);
- Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
- }
- } else if (!from.isBareJid()){
+ if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) {
+ mucOptions.setOnline();
+ mucOptions.setSelf(user);
+ if (mucOptions.mNickChangingInProgress) {
+ if (mucOptions.onRenameListener != null) {
+ mucOptions.onRenameListener.onSuccess();
+ }
+ mucOptions.mNickChangingInProgress = false;
+ }
+ } else {
+ mucOptions.updateUser(user);
+ }
+ if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) {
+ Log.d(Config.LOGTAG, mucOptions.getAccount().getJid().toBareJid()
+ + ": room '"
+ + mucOptions.getConversation().getJid().toBareJid()
+ + "' created. pushing default configuration");
+ mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(),
+ IqGenerator.defaultRoomConfiguration(),
+ null);
+ }
+ if (mXmppConnectionService.getPgpEngine() != null) {
+ Element signed = packet.findChild("x", "jabber:x:signed");
+ if (signed != null) {
+ Element status = packet.findChild("status");
+ String msg = status == null ? "" : status.getContent();
+ long keyId = mXmppConnectionService.getPgpEngine().fetchKeyId(mucOptions.getAccount(), msg, signed.getContent());
+ if (keyId != 0) {
+ user.setPgpKeyId(keyId);
+ }
+ }
+ }
+ if (avatar != null) {
+ avatar.owner = from;
+ if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
+ if (user.setAvatar(avatar)) {
+ mXmppConnectionService.getAvatarService().clear(user);
+ }
+ } else if (mXmppConnectionService.isDataSaverDisabled()) {
+ mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar);
+ }
+ }
+ }
+ }
+ } else if (type.equals("unavailable")) {
+ if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) ||
+ packet.getFrom().equals(mucOptions.getConversation().getJid())) {
+ if (codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) {
+ mucOptions.mNickChangingInProgress = true;
+ } else if (codes.contains(MucOptions.STATUS_CODE_KICKED)) {
+ mucOptions.setError(MucOptions.Error.KICKED);
+ } else if (codes.contains(MucOptions.STATUS_CODE_BANNED)) {
+ mucOptions.setError(MucOptions.Error.BANNED);
+ } else if (codes.contains(MucOptions.STATUS_CODE_LOST_MEMBERSHIP)) {
+ mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
+ } else if (codes.contains(MucOptions.STATUS_CODE_AFFILIATION_CHANGE)) {
+ mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
+ } else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN)) {
+ mucOptions.setError(MucOptions.Error.SHUTDOWN);
+ } else {
+ mucOptions.setError(MucOptions.Error.UNKNOWN);
+ Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
+ }
+ } else if (!from.isBareJid()) {
Element item = x.findChild("item");
if (item != null) {
mucOptions.updateUser(parseItem(conversation, item, from));
}
- MucOptions.User user = mucOptions.deleteUser(from);
- if (user != null) {
- mXmppConnectionService.getAvatarService().clear(user);
- }
- }
- } else if (type.equals("error")) {
- Element error = packet.findChild("error");
- if (error != null && error.hasChild("conflict")) {
- if (mucOptions.online()) {
- if (mucOptions.onRenameListener != null) {
- mucOptions.onRenameListener.onFailure();
- }
- } else {
- mucOptions.setError(MucOptions.Error.NICK_IN_USE);
- }
- } else if (error != null && error.hasChild("not-authorized")) {
- mucOptions.setError(MucOptions.Error.PASSWORD_REQUIRED);
- } else if (error != null && error.hasChild("forbidden")) {
- mucOptions.setError(MucOptions.Error.BANNED);
- } else if (error != null && error.hasChild("registration-required")) {
- mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
- }
- }
- }
- }
+ MucOptions.User user = mucOptions.deleteUser(from);
+ if (user != null) {
+ mXmppConnectionService.getAvatarService().clear(user);
+ }
+ }
+ } else if (type.equals("error")) {
+ Element error = packet.findChild("error");
+ if (error != null && error.hasChild("conflict")) {
+ if (mucOptions.online()) {
+ if (mucOptions.onRenameListener != null) {
+ mucOptions.onRenameListener.onFailure();
+ }
+ } else {
+ mucOptions.setError(MucOptions.Error.NICK_IN_USE);
+ }
+ } else if (error != null && error.hasChild("not-authorized")) {
+ mucOptions.setError(MucOptions.Error.PASSWORD_REQUIRED);
+ } else if (error != null && error.hasChild("forbidden")) {
+ mucOptions.setError(MucOptions.Error.BANNED);
+ } else if (error != null && error.hasChild("registration-required")) {
+ mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
+ }
+ }
+ }
+ }
- private static List<String> getStatusCodes(Element x) {
- List<String> codes = new ArrayList<>();
- if (x != null) {
- for (Element child : x.getChildren()) {
- if (child.getName().equals("status")) {
- String code = child.getAttribute("code");
- if (code != null) {
- codes.add(code);
- }
- }
- }
- }
- return codes;
- }
+ private static List<String> getStatusCodes(Element x) {
+ List<String> codes = new ArrayList<>();
+ if (x != null) {
+ for (Element child : x.getChildren()) {
+ if (child.getName().equals("status")) {
+ String code = child.getAttribute("code");
+ if (code != null) {
+ codes.add(code);
+ }
+ }
+ }
+ }
+ return codes;
+ }
- public void parseContactPresence(final PresencePacket packet, final Account account) {
- final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
- final Jid from = packet.getFrom();
- if (from == null || from.equals(account.getJid())) {
- return;
- }
- final String type = packet.getAttribute("type");
- final Contact contact = account.getRoster().getContact(from);
- if (type == null) {
- final String resource = from.isBareJid() ? "" : from.getResourcepart();
- contact.setPresenceName(packet.findChildContent("nick", "http://jabber.org/protocol/nick"));
- Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
+ public void parseContactPresence(final PresencePacket packet, final Account account) {
+ final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
+ final Jid from = packet.getFrom();
+ if (from == null || from.equals(account.getJid())) {
+ return;
+ }
+ final String type = packet.getAttribute("type");
+ final Contact contact = account.getRoster().getContact(from);
+ if (type == null) {
+ final String resource = from.isBareJid() ? "" : from.getResourcepart();
+ contact.setPresenceName(packet.findChildContent("nick", "http://jabber.org/protocol/nick"));
+ Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
if (avatar != null && (!contact.isSelf() || account.getAvatar() == null)) {
avatar.owner = from.toBareJid();
- if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
+ if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
if (avatar.owner.equals(account.getJid().toBareJid())) {
account.setAvatar(avatar.getFilename());
mXmppConnectionService.databaseBackend.updateAccount(account);
@@ -197,86 +197,86 @@ public class PresenceParser extends AbstractParser implements
} else if (contact.setAvatar(avatar)) {
mXmppConnectionService.getAvatarService().clear(contact);
mXmppConnectionService.updateConversationUi();
- mXmppConnectionService.updateRosterUi();
- }
- } else if (mXmppConnectionService.isDataSaverDisabled()){
- mXmppConnectionService.fetchAvatar(account, avatar);
- }
- }
- int sizeBefore = contact.getPresences().size();
+ mXmppConnectionService.updateRosterUi();
+ }
+ } else if (mXmppConnectionService.isDataSaverDisabled()) {
+ mXmppConnectionService.fetchAvatar(account, avatar);
+ }
+ }
+ int sizeBefore = contact.getPresences().size();
- final String show = packet.findChildContent("show");
- final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
- final String message = packet.findChildContent("status");
- final Presence presence = Presence.parse(show, caps, message);
- contact.updatePresence(resource, presence);
- if (presence.hasCaps()) {
- mXmppConnectionService.fetchCaps(account, from, presence);
- }
+ final String show = packet.findChildContent("show");
+ final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
+ final String message = packet.findChildContent("status");
+ final Presence presence = Presence.parse(show, caps, message);
+ contact.updatePresence(resource, presence);
+ if (presence.hasCaps()) {
+ mXmppConnectionService.fetchCaps(account, from, presence);
+ }
- final Element idle = packet.findChild("idle","urn:xmpp:idle:1");
- if (idle != null) {
- contact.flagInactive();
- String since = idle.getAttribute("since");
- try {
- contact.setLastseen(AbstractParser.parseTimestamp(since));
- } catch (NullPointerException | ParseException e) {
- contact.setLastseen(System.currentTimeMillis());
- }
- } else {
- contact.flagActive();
- contact.setLastseen(AbstractParser.parseTimestamp(packet));
- }
+ final Element idle = packet.findChild("idle", "urn:xmpp:idle:1");
+ if (idle != null) {
+ contact.flagInactive();
+ String since = idle.getAttribute("since");
+ try {
+ contact.setLastseen(AbstractParser.parseTimestamp(since));
+ } catch (NullPointerException | ParseException e) {
+ contact.setLastseen(System.currentTimeMillis());
+ }
+ } else {
+ contact.flagActive();
+ contact.setLastseen(AbstractParser.parseTimestamp(packet));
+ }
- PgpEngine pgp = mXmppConnectionService.getPgpEngine();
- Element x = packet.findChild("x", "jabber:x:signed");
- if (pgp != null && x != null) {
- Element status = packet.findChild("status");
- String msg = status != null ? status.getContent() : "";
- contact.setPgpKeyId(pgp.fetchKeyId(account, msg, x.getContent()));
- }
- boolean online = sizeBefore < contact.getPresences().size();
- mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
- } else if (type.equals("unavailable")) {
- if (from.isBareJid()) {
- contact.clearPresences();
- } else {
- contact.removePresence(from.getResourcepart());
- }
- mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
- } else if (type.equals("subscribe")) {
- if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
- mXmppConnectionService.sendPresencePacket(account,
- mPresenceGenerator.sendPresenceUpdatesTo(contact));
- } else {
- contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
- final Conversation conversation = mXmppConnectionService.findOrCreateConversation(
- account, contact.getJid().toBareJid(), false);
- final String statusMessage = packet.findChildContent("status");
- if (statusMessage != null
- && !statusMessage.isEmpty()
- && conversation.countMessages() == 0) {
- conversation.add(new Message(
- conversation,
- statusMessage,
- Message.ENCRYPTION_NONE,
- Message.STATUS_RECEIVED
- ));
- }
- }
- }
- mXmppConnectionService.updateRosterUi();
- }
+ PgpEngine pgp = mXmppConnectionService.getPgpEngine();
+ Element x = packet.findChild("x", "jabber:x:signed");
+ if (pgp != null && x != null) {
+ Element status = packet.findChild("status");
+ String msg = status != null ? status.getContent() : "";
+ contact.setPgpKeyId(pgp.fetchKeyId(account, msg, x.getContent()));
+ }
+ boolean online = sizeBefore < contact.getPresences().size();
+ mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
+ } else if (type.equals("unavailable")) {
+ if (from.isBareJid()) {
+ contact.clearPresences();
+ } else {
+ contact.removePresence(from.getResourcepart());
+ }
+ mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
+ } else if (type.equals("subscribe")) {
+ if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
+ mXmppConnectionService.sendPresencePacket(account,
+ mPresenceGenerator.sendPresenceUpdatesTo(contact));
+ } else {
+ contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
+ final Conversation conversation = mXmppConnectionService.findOrCreateConversation(
+ account, contact.getJid().toBareJid(), false);
+ final String statusMessage = packet.findChildContent("status");
+ if (statusMessage != null
+ && !statusMessage.isEmpty()
+ && conversation.countMessages() == 0) {
+ conversation.add(new Message(
+ conversation,
+ statusMessage,
+ Message.ENCRYPTION_NONE,
+ Message.STATUS_RECEIVED
+ ));
+ }
+ }
+ }
+ mXmppConnectionService.updateRosterUi();
+ }
- @Override
- public void onPresencePacketReceived(Account account, PresencePacket packet) {
- if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
- this.parseConferencePresence(packet, account);
- } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
- this.parseConferencePresence(packet, account);
- } else {
- this.parseContactPresence(packet, account);
- }
- }
+ @Override
+ public void onPresencePacketReceived(Account account, PresencePacket packet) {
+ if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
+ this.parseConferencePresence(packet, account);
+ } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
+ this.parseConferencePresence(packet, account);
+ } else {
+ this.parseContactPresence(packet, account);
+ }
+ }
}