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