summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Young <consult.awy@gmail.com>2014-11-13 06:42:37 (GMT)
committerAlan Young <consult.awy@gmail.com>2015-04-10 06:50:58 (GMT)
commit7d2101b93b6253c3ea15b663f7f3dc385cb21364 (patch)
treed81338baf0d117e83cdc07f882cbedd9471e834d /src/com/isode/stroke/presence
parenta20ca7ba40d837abe228462be0aba5d32d6831e3 (diff)
downloadstroke-7d2101b93b6253c3ea15b663f7f3dc385cb21364.zip
stroke-7d2101b93b6253c3ea15b663f7f3dc385cb21364.tar.bz2
Checkpoint - A bunch of initial stuff for Android
MemoryStorages, Storages NickManager, NickResolver CryptoProvider, Hash, SafeByteArray, JavaCryptoProvider CapsInfoGenerator, CapsManager, CapsMemoryStorage, CapsProvider, CapsStorage, CapsInfo CapsInfoSerializer, CapsInfoParser ClientDiscoManager, DiscoInfoResponder, EntityCapsManager, EntityCapsProvider GetDiscoInfoRequest ChatState, Idle Presence, PayloadAddingPresenceSender, PresenceOracle, SubscriptionManager StatusSerializer, StatusShowSerializer, StatusParser, StatusShowParser, Replace, ReplaceParser, ReplaceSerializer SecurityLabel, SecurityLabelsCatalog, GetSecurityLabelsCatalogRequest VCard, GetVCardRequest, SetVCardRequest, VCardManager, VCardMemoryStorage, VCardStorage RosterMemoryStorage, RosterPushResponder, RosterStorage, SetRosterRequest XMPPRoster, XMPPRosterController, XMPPRosterImpl, XMPPRosterItem GetRosterRequest, SetResponder Add parsers and serializers for Idle, VCard, PrivateStorage & Stroage. Add parser for Subject. Add impromptu flag to MUCInvitation. Update copyrights. Change-Id: I9949f506b70e60b3a64f1dadde8f9b235b322e1d
Diffstat (limited to 'src/com/isode/stroke/presence')
-rw-r--r--src/com/isode/stroke/presence/PayloadAddingPresenceSender.java62
-rw-r--r--src/com/isode/stroke/presence/PresenceOracle.java127
-rw-r--r--src/com/isode/stroke/presence/SubscriptionManager.java68
3 files changed, 257 insertions, 0 deletions
diff --git a/src/com/isode/stroke/presence/PayloadAddingPresenceSender.java b/src/com/isode/stroke/presence/PayloadAddingPresenceSender.java
new file mode 100644
index 0000000..ed6106b
--- /dev/null
+++ b/src/com/isode/stroke/presence/PayloadAddingPresenceSender.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010-2015, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.presence;
+
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.elements.Presence;
+
+public class PayloadAddingPresenceSender implements PresenceSender {
+ private Presence lastSentPresence;
+ private final PresenceSender sender;
+ private Payload payload;
+
+ public PayloadAddingPresenceSender(PresenceSender sender) {
+ this.sender = sender;
+ }
+
+ public void sendPresence(Presence presence) {
+ if (presence.isAvailable()) {
+ if (presence.getTo() != null && !presence.getTo().isValid()) {
+ lastSentPresence = presence;
+ }
+ } else {
+ lastSentPresence = null;
+ }
+ if (payload != null) {
+ Presence sentPresence = presence;
+ sentPresence.updatePayload(payload);
+ sender.sendPresence(sentPresence);
+ } else {
+ sender.sendPresence(presence);
+ }
+ }
+
+ public boolean isAvailable() {
+ return sender.isAvailable();
+ }
+
+ /**
+ * Sets the payload to be added to outgoing presences. If initial presence
+ * has been sent, this will resend the last sent presence with an updated
+ * payload. Initial presence is reset when unavailable presence is sent, or
+ * when reset() is called.
+ */
+ public void setPayload(Payload payload) {
+ this.payload = payload;
+ if (lastSentPresence != null) {
+ sendPresence(lastSentPresence);
+ }
+ }
+
+ /**
+ * Resets the presence sender. This puts the presence sender back in the
+ * initial state (before initial presence has been sent). This also resets
+ * the chained sender.
+ */
+ public void reset() {
+ lastSentPresence = null;
+ }
+
+}
diff --git a/src/com/isode/stroke/presence/PresenceOracle.java b/src/com/isode/stroke/presence/PresenceOracle.java
new file mode 100644
index 0000000..8d63f59
--- /dev/null
+++ b/src/com/isode/stroke/presence/PresenceOracle.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2010-2015, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.presence;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.isode.stroke.client.StanzaChannel;
+import com.isode.stroke.elements.Presence;
+import com.isode.stroke.elements.StatusShow;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.signals.Signal1;
+import com.isode.stroke.signals.SignalConnection;
+import com.isode.stroke.signals.Slot1;
+
+public class PresenceOracle {
+ private final Map<JID,Map<JID,Presence>> entries_ = new HashMap<JID,Map<JID,Presence>>();
+ private final StanzaChannel stanzaChannel_;
+ private final SignalConnection onPresenceReceivedSignal;
+ private final SignalConnection onAvailableChangedSignal;
+
+
+ public final Signal1<Presence> onPresenceChange = new Signal1<Presence>();
+
+ public PresenceOracle(StanzaChannel stanzaChannel) {
+ stanzaChannel_ = stanzaChannel;
+ onPresenceReceivedSignal = stanzaChannel_.onPresenceReceived.connect(new Slot1<Presence>() {
+ @Override
+ public void call(Presence p1) {
+ handleIncomingPresence(p1);
+ }
+ });
+ onAvailableChangedSignal = stanzaChannel_.onAvailableChanged.connect(new Slot1<Boolean>() {
+ @Override
+ public void call(Boolean p1) {
+ handleStanzaChannelAvailableChanged(p1);
+ }
+ });
+ }
+
+ void delete() {
+ onPresenceReceivedSignal.disconnect();
+ onAvailableChangedSignal.disconnect();
+ }
+
+ void handleStanzaChannelAvailableChanged(boolean available) {
+ if (available) {
+ entries_.clear();
+ }
+ }
+
+
+ void handleIncomingPresence(Presence presence) {
+ JID bareJID = presence.getFrom().toBare();
+ if (presence.getType() == Presence.Type.Subscribe) {
+ }
+ else {
+ Presence passedPresence = presence;
+ if (presence.getType() == Presence.Type.Unsubscribe) {
+ /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
+ passedPresence = new Presence();
+ passedPresence.setType(Presence.Type.Unavailable);
+ passedPresence.setFrom(bareJID);
+ passedPresence.setStatus(presence.getStatus());
+ }
+ Map<JID,Presence> jidMap = entries_.get(bareJID);
+ if (jidMap == null) jidMap = new HashMap<JID,Presence>();
+ if (passedPresence.getFrom().isBare() && presence.getType() == Presence.Type.Unavailable) {
+ /* Have a bare-JID only presence of offline */
+ jidMap.clear();
+ } else if (passedPresence.getType() == Presence.Type.Available) {
+ /* Don't have a bare-JID only offline presence once there are available presences */
+ jidMap.remove(bareJID);
+ }
+ if (passedPresence.getType() == Presence.Type.Unavailable && jidMap.size() > 1) {
+ jidMap.remove(passedPresence.getFrom());
+ } else {
+ jidMap.put(passedPresence.getFrom(), passedPresence);
+ }
+ entries_.put(bareJID, jidMap);
+ onPresenceChange.emit(passedPresence);
+ }
+ }
+
+ public Presence getLastPresence(final JID jid) {
+ Map<JID,Presence> presenceMap = entries_.get(jid.toBare());
+ if (presenceMap == null) return new Presence();
+
+ Presence i = presenceMap.get(jid);
+ if (i != null) {
+ return i;
+ } else {
+ return new Presence();
+ }
+ }
+
+ public Collection<Presence> getAllPresence(final JID bareJID) {
+ Collection<Presence> results = new ArrayList<Presence>();
+
+ Map<JID,Presence> presenceMap = entries_.get(bareJID);
+ if (presenceMap == null) return results;
+
+ results.addAll(presenceMap.values());
+ return results;
+ }
+
+ public Presence getHighestPriorityPresence(final JID bareJID) {
+ Map<JID,Presence> presenceMap = entries_.get(bareJID);
+ if (presenceMap == null) return new Presence();
+
+ Presence highest = null;
+ for (Presence current : presenceMap.values()) {
+ if (highest == null
+ || current.getPriority() > highest.getPriority()
+ || (current.getPriority() == highest.getPriority()
+ && StatusShow.typeToAvailabilityOrdering(current.getShow()) > StatusShow.typeToAvailabilityOrdering(highest.getShow()))) {
+ highest = current;
+ }
+
+ }
+ return highest;
+ }
+}
diff --git a/src/com/isode/stroke/presence/SubscriptionManager.java b/src/com/isode/stroke/presence/SubscriptionManager.java
new file mode 100644
index 0000000..91075fc
--- /dev/null
+++ b/src/com/isode/stroke/presence/SubscriptionManager.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010-2015, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.presence;
+
+import com.isode.stroke.client.StanzaChannel;
+import com.isode.stroke.elements.Presence;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.signals.Signal2;
+import com.isode.stroke.signals.Signal3;
+import com.isode.stroke.signals.SignalConnection;
+import com.isode.stroke.signals.Slot1;
+
+public class SubscriptionManager {
+ private StanzaChannel stanzaChannel;
+ private SignalConnection onPresenceReceivedConnection;
+
+ public final Signal3<JID, String, Presence> onPresenceSubscriptionRequest = new Signal3<JID, String, Presence>();
+
+ public final Signal2<JID, String> onPresenceSubscriptionRevoked = new Signal2<JID, String>();
+
+ public SubscriptionManager(StanzaChannel channel) {
+ stanzaChannel = channel;
+ onPresenceReceivedConnection = stanzaChannel.onPresenceReceived.connect(new Slot1<Presence>() {
+ @Override
+ public void call(Presence p1) {
+ handleIncomingPresence(p1);
+ }
+ });
+ }
+
+ void delete() {
+ onPresenceReceivedConnection.disconnect();
+ }
+
+ public void cancelSubscription(final JID jid) {
+ Presence stanza = new Presence();
+ stanza.setType(Presence.Type.Unsubscribed);
+ stanza.setTo(jid);
+ stanzaChannel.sendPresence(stanza);
+ }
+
+ public void confirmSubscription(final JID jid) {
+ Presence stanza = new Presence();
+ stanza.setType(Presence.Type.Subscribed);
+ stanza.setTo(jid);
+ stanzaChannel.sendPresence(stanza);
+ }
+
+
+ public void requestSubscription(final JID jid) {
+ Presence stanza = new Presence();
+ stanza.setType(Presence.Type.Subscribe);
+ stanza.setTo(jid);
+ stanzaChannel.sendPresence(stanza);
+ }
+
+ void handleIncomingPresence(Presence presence) {
+ JID bareJID = presence.getFrom().toBare();
+ if (presence.getType() == Presence.Type.Subscribe) {
+ onPresenceSubscriptionRequest.emit(bareJID, presence.getStatus(), presence);
+ }
+ else if (presence.getType() == Presence.Type.Unsubscribe) {
+ onPresenceSubscriptionRevoked.emit(bareJID, presence.getStatus());
+ }
+ }
+}