1package eu.siacs.conversations.parser;
2
3import java.util.ArrayList;
4
5import eu.siacs.conversations.crypto.PgpEngine;
6import eu.siacs.conversations.entities.Account;
7import eu.siacs.conversations.entities.Contact;
8import eu.siacs.conversations.entities.Conversation;
9import eu.siacs.conversations.entities.MucOptions;
10import eu.siacs.conversations.entities.Presences;
11import eu.siacs.conversations.generator.PresenceGenerator;
12import eu.siacs.conversations.services.XmppConnectionService;
13import eu.siacs.conversations.xml.Element;
14import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
15import eu.siacs.conversations.xmpp.jid.Jid;
16import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
17
18public class PresenceParser extends AbstractParser implements
19 OnPresencePacketReceived {
20
21 public PresenceParser(XmppConnectionService service) {
22 super(service);
23 }
24
25 public void parseConferencePresence(PresencePacket packet, Account account) {
26 PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
27 final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().toBareJid());
28 if (conversation != null) {
29 final MucOptions mucOptions = conversation.getMucOptions();
30 boolean before = mucOptions.online();
31 int count = mucOptions.getUsers().size();
32 final ArrayList<MucOptions.User> tileUserBefore = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),4)));
33 mucOptions.processPacket(packet, mPgpEngine);
34 final ArrayList<MucOptions.User> tileUserAfter = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),4)));
35 if (!tileUserAfter.equals(tileUserBefore)) {
36 mXmppConnectionService.getAvatarService().clear(conversation);
37 }
38 if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUsers().size())) {
39 mXmppConnectionService.updateConversationUi();
40 } else if (mucOptions.online()) {
41 mXmppConnectionService.updateMucRosterUi();
42 }
43 }
44 }
45
46 public void parseContactPresence(PresencePacket packet, Account account) {
47 PresenceGenerator mPresenceGenerator = mXmppConnectionService
48 .getPresenceGenerator();
49 if (packet.getFrom() == null) {
50 return;
51 }
52 final Jid from = packet.getFrom();
53 String type = packet.getAttribute("type");
54 Contact contact = account.getRoster().getContact(packet.getFrom());
55 if (type == null) {
56 String presence;
57 if (!from.isBareJid()) {
58 presence = from.getResourcepart();
59 } else {
60 presence = "";
61 }
62 int sizeBefore = contact.getPresences().size();
63 contact.updatePresence(presence,
64 Presences.parseShow(packet.findChild("show")));
65 PgpEngine pgp = mXmppConnectionService.getPgpEngine();
66 if (pgp != null) {
67 Element x = packet.findChild("x", "jabber:x:signed");
68 if (x != null) {
69 Element status = packet.findChild("status");
70 String msg;
71 if (status != null) {
72 msg = status.getContent();
73 } else {
74 msg = "";
75 }
76 contact.setPgpKeyId(pgp.fetchKeyId(account, msg,
77 x.getContent()));
78 }
79 }
80 boolean online = sizeBefore < contact.getPresences().size();
81 updateLastseen(packet, account, false);
82 mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
83 } else if (type.equals("unavailable")) {
84 if (from.isBareJid()) {
85 contact.clearPresences();
86 } else {
87 contact.removePresence(from.getResourcepart());
88 }
89 mXmppConnectionService.onContactStatusChanged
90 .onContactStatusChanged(contact, false);
91 } else if (type.equals("subscribe")) {
92 if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
93 mXmppConnectionService.sendPresencePacket(account,
94 mPresenceGenerator.sendPresenceUpdatesTo(contact));
95 } else {
96 contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
97 }
98 }
99 Element nick = packet.findChild("nick",
100 "http://jabber.org/protocol/nick");
101 if (nick != null) {
102 contact.setPresenceName(nick.getContent());
103 }
104 mXmppConnectionService.updateRosterUi();
105 }
106
107 @Override
108 public void onPresencePacketReceived(Account account, PresencePacket packet) {
109 if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
110 this.parseConferencePresence(packet, account);
111 } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
112 this.parseConferencePresence(packet, account);
113 } else {
114 this.parseContactPresence(packet, account);
115 }
116 }
117
118}