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.stanzas.PresencePacket;
13
14public class PresenceParser extends AbstractParser implements
15 OnPresencePacketReceived {
16
17 private PresenceGenerator mPresenceGenerator;
18
19 public PresenceParser(XmppConnectionService service) {
20 super(service);
21 mPresenceGenerator = service.getPresenceGenerator();
22 }
23
24 public void parseConferencePresence(PresencePacket packet, Account account) {
25 PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
26 if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
27 Conversation muc = mXmppConnectionService.findMuc(packet
28 .getAttribute("from").split("/")[0], account);
29 if (muc != null) {
30 muc.getMucOptions().processPacket(packet, mPgpEngine);
31 }
32 } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
33 Conversation muc = mXmppConnectionService.findMuc(packet
34 .getAttribute("from").split("/")[0], account);
35 if (muc != null) {
36 int error = muc.getMucOptions().getError();
37 muc.getMucOptions().processPacket(packet, mPgpEngine);
38 if (muc.getMucOptions().getError() != error) {
39 mXmppConnectionService.updateUi(muc, false);
40 }
41 }
42 }
43 }
44
45 public void parseContactPresence(PresencePacket packet, Account account) {
46 if (packet.getFrom() == null) {
47 return;
48 }
49 String[] fromParts = packet.getFrom().split("/");
50 String type = packet.getAttribute("type");
51 if (fromParts[0].equals(account.getJid())) {
52 if (fromParts.length == 2) {
53 if (type == null) {
54 account.updatePresence(fromParts[1],
55 Presences.parseShow(packet.findChild("show")));
56 } else if (type.equals("unavailable")) {
57 account.removePresence(fromParts[1]);
58 }
59 }
60
61 } else {
62 Contact contact = account.getRoster().getContact(packet.getFrom());
63 if (type == null) {
64 if (fromParts.length == 2) {
65 int sizeBefore = contact.getPresences().size();
66 contact.updatePresence(fromParts[1],
67 Presences.parseShow(packet.findChild("show")));
68 PgpEngine pgp = mXmppConnectionService.getPgpEngine();
69 if (pgp != null) {
70 Element x = packet.findChild("x", "jabber:x:signed");
71 if (x != null) {
72 Element status = packet.findChild("status");
73 String msg;
74 if (status != null) {
75 msg = status.getContent();
76 } else {
77 msg = "";
78 }
79 contact.setPgpKeyId(pgp.fetchKeyId(account, msg,
80 x.getContent()));
81 }
82 }
83 boolean online = sizeBefore < contact.getPresences().size();
84 updateLastseen(packet, account, true);
85 mXmppConnectionService.onContactStatusChanged
86 .onContactStatusChanged(contact, online);
87 }
88 } else if (type.equals("unavailable")) {
89 if (fromParts.length != 2) {
90 contact.clearPresences();
91 } else {
92 contact.removePresence(fromParts[1]);
93 }
94 mXmppConnectionService.onContactStatusChanged
95 .onContactStatusChanged(contact, false);
96 } else if (type.equals("subscribe")) {
97 if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
98 mXmppConnectionService.sendPresencePacket(account, mPresenceGenerator.stopPresenceUpdatesTo(contact));
99 if ((contact.getOption(Contact.Options.ASKING))
100 && (!contact.getOption(Contact.Options.TO))) {
101 mXmppConnectionService.sendPresencePacket(account,mPresenceGenerator.requestPresenceUpdatesFrom(contact));
102 }
103 } else {
104 contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
105 }
106 }
107 }
108 }
109
110 @Override
111 public void onPresencePacketReceived(Account account, PresencePacket packet) {
112 if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
113 this.parseConferencePresence(packet, account);
114 } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
115 this.parseConferencePresence(packet, account);
116 } else {
117 this.parseContactPresence(packet, account);
118 }
119 }
120
121}