aboutsummaryrefslogtreecommitdiffstats
path: root/conversations/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
blob: 4e90cda8ccfb1f8cdd35a7a753d5e56cea0d1e3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package eu.siacs.conversations.parser;

import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.generator.PresenceGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;

public class PresenceParser extends AbstractParser implements
		OnPresencePacketReceived {

	public PresenceParser(XmppConnectionService service) {
		super(service);
	}

	public void parseConferencePresence(PresencePacket packet, Account account) {
		PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
		if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
			Conversation muc = mXmppConnectionService.find(account, packet
					.getAttribute("from").split("/", 2)[0]);
			if (muc != null) {
				boolean before = muc.getMucOptions().online();
				muc.getMucOptions().processPacket(packet, mPgpEngine);
				if (before != muc.getMucOptions().online()) {
					mXmppConnectionService.updateConversationUi();
				}
				mXmppConnectionService.getAvatarService().clear(muc);
			}
		} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
			Conversation muc = mXmppConnectionService.find(account, packet
					.getAttribute("from").split("/", 2)[0]);
			if (muc != null) {
				boolean before = muc.getMucOptions().online();
				muc.getMucOptions().processPacket(packet, mPgpEngine);
				if (before != muc.getMucOptions().online()) {
					mXmppConnectionService.updateConversationUi();
				}
				mXmppConnectionService.getAvatarService().clear(muc);
			}
		}
	}

	public void parseContactPresence(PresencePacket packet, Account account) {
		PresenceGenerator mPresenceGenerator = mXmppConnectionService
				.getPresenceGenerator();
		if (packet.getFrom() == null) {
			return;
		}
		String[] fromParts = packet.getFrom().split("/", 2);
		String type = packet.getAttribute("type");
		if (fromParts[0].equals(account.getJid())) {
			if (fromParts.length == 2) {
				if (type == null) {
					account.updatePresence(fromParts[1],
							Presences.parseShow(packet.findChild("show")));
				} else if (type.equals("unavailable")) {
					account.removePresence(fromParts[1]);
					account.deactivateGracePeriod();
				}
			}
		} else {
			Contact contact = account.getRoster().getContact(packet.getFrom());
			if (type == null) {
				String presence;
				if (fromParts.length >= 2) {
					presence = fromParts[1];
				} else {
					presence = "";
				}
				int sizeBefore = contact.getPresences().size();
				contact.updatePresence(presence,
						Presences.parseShow(packet.findChild("show")));
				PgpEngine pgp = mXmppConnectionService.getPgpEngine();
				if (pgp != null) {
					Element x = packet.findChild("x", "jabber:x:signed");
					if (x != null) {
						Element status = packet.findChild("status");
						String msg;
						if (status != null) {
							msg = status.getContent();
						} else {
							msg = "";
						}
						contact.setPgpKeyId(pgp.fetchKeyId(account, msg,
								x.getContent()));
					}
				}
				boolean online = sizeBefore < contact.getPresences().size();
				updateLastseen(packet, account, true);
				mXmppConnectionService.onContactStatusChanged
						.onContactStatusChanged(contact, online);
			} else if (type.equals("unavailable")) {
				if (fromParts.length != 2) {
					contact.clearPresences();
				} else {
					contact.removePresence(fromParts[1]);
				}
				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);
				}
			}
			Element nick = packet.findChild("nick",
					"http://jabber.org/protocol/nick");
			if (nick != null) {
				contact.setPresenceName(nick.getContent());
			}
		}
		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);
		}
	}

}