aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java166
1 files changed, 153 insertions, 13 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java
index 8bc5ec89..79ffa9bf 100644
--- a/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java
+++ b/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java
@@ -1,18 +1,25 @@
package de.thedevstack.conversationsplus.parser;
+import android.util.Log;
+
import java.util.ArrayList;
+import java.util.List;
+
+import de.thedevstack.android.logcat.Logging;
+import de.thedevstack.conversationsplus.utils.AvatarUtil;
+import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
+import de.thedevstack.conversationsplus.Config;
import de.thedevstack.conversationsplus.crypto.PgpEngine;
import de.thedevstack.conversationsplus.entities.Account;
import de.thedevstack.conversationsplus.entities.Contact;
import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.entities.MucOptions;
-import de.thedevstack.conversationsplus.entities.Presences;
+import de.thedevstack.conversationsplus.entities.Presence;
import de.thedevstack.conversationsplus.generator.PresenceGenerator;
import de.thedevstack.conversationsplus.services.AvatarService;
import de.thedevstack.conversationsplus.services.XmppConnectionService;
-import de.thedevstack.conversationsplus.utils.AvatarUtil;
-import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
import de.thedevstack.conversationsplus.xml.Element;
import de.thedevstack.conversationsplus.xmpp.OnPresencePacketReceived;
import de.thedevstack.conversationsplus.xmpp.jid.Jid;
@@ -27,19 +34,19 @@ public class PresenceParser extends AbstractParser implements
}
public void parseConferencePresence(PresencePacket packet, Account account) {
- PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
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.getUsers().size();
- final ArrayList<MucOptions.User> tileUserBefore = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5)));
- mucOptions.processPacket(packet, mPgpEngine);
- final ArrayList<MucOptions.User> tileUserAfter = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5)));
+ int count = mucOptions.getUserCount();
+ final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
+ processConferencePresence(packet, mucOptions);
+ final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
if (!tileUserAfter.equals(tileUserBefore)) {
+ Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": update tiles for " + conversation.getName());
AvatarService.getInstance().clear(conversation);
}
- if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUsers().size())) {
+ if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
UiUpdateHelper.updateConversationUi();
} else if (mucOptions.online()) {
UiUpdateHelper.updateMucRosterUi();
@@ -47,8 +54,120 @@ public class PresenceParser extends AbstractParser implements
}
}
- public void parseContactPresence(PresencePacket packet, Account account) {
- PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
+ private void processConferencePresence(PresencePacket packet, MucOptions mucOptions) {
+ 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 = new MucOptions.User(mucOptions,from);
+ user.setAffiliation(item.getAttribute("affiliation"));
+ user.setRole(item.getAttribute("role"));
+ user.setJid(item.getAttributeAsJid("jid"));
+ 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.addUser(user);
+ }
+ 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 (AvatarUtil.isAvatarCached(avatar)) {
+ if (user.setAvatar(avatar)) {
+ AvatarService.getInstance().clear(user);
+ }
+ } else {
+ AvatarService.getInstance().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()){
+ MucOptions.User user = mucOptions.deleteUser(from.getResourcepart());
+ if (user != null) {
+ AvatarService.getInstance().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.BANNED);
+ }
+ }
+ }
+ }
+
+ 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) {
return;
@@ -56,7 +175,7 @@ public class PresenceParser extends AbstractParser implements
final String type = packet.getAttribute("type");
final Contact contact = account.getRoster().getContact(from);
if (type == null) {
- String presence = from.isBareJid() ? "" : from.getResourcepart();
+ 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()) {
@@ -72,7 +191,15 @@ public class PresenceParser extends AbstractParser implements
}
}
int sizeBefore = contact.getPresences().size();
- contact.updatePresence(presence, Presences.parseShow(packet.findChild("show")));
+
+ final String show = packet.findChildContent("show");
+ final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
+ final Presence presence = Presence.parse(show, caps);
+ contact.updatePresence(resource, presence);
+ if (presence.hasCaps() && Config.REQUEST_DISCO) {
+ mXmppConnectionService.fetchCaps(account, from, presence);
+ }
+
PgpEngine pgp = mXmppConnectionService.getPgpEngine();
Element x = packet.findChild("x", "jabber:x:signed");
if (pgp != null && x != null) {
@@ -96,6 +223,19 @@ public class PresenceParser extends AbstractParser implements
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
+ ));
+ }
}
}
UiUpdateHelper.updateRosterUi();