diff --git a/source/org/jivesoftware/smack/Roster.java b/source/org/jivesoftware/smack/Roster.java index 32d4457da..8648f9077 100644 --- a/source/org/jivesoftware/smack/Roster.java +++ b/source/org/jivesoftware/smack/Roster.java @@ -668,8 +668,9 @@ public class Roster { userPresences.put(StringUtils.parseResource(from), presence); // If the user is in the roster, fire an event. RosterEntry entry = entries.get(key); - if (entry != null) + if (entry != null) { fireRosterPresenceEvent(presence); + } } // If an "unavailable" packet. else if (presence.getType() == Presence.Type.unavailable) { @@ -696,8 +697,9 @@ public class Roster { } // If the user is in the roster, fire an event. RosterEntry entry = entries.get(key); - if (entry != null) + if (entry != null) { fireRosterPresenceEvent(presence); + } } else if (presence.getType() == Presence.Type.subscribe) { if (subscriptionMode == SubscriptionMode.accept_all) { @@ -725,6 +727,29 @@ public class Roster { } // Otherwise, in manual mode so ignore. } + // Error presence packets from a bare JID mean we invalidate all existing + // presence info for the user. + else if (presence.getType() == Presence.Type.error && + "".equals(StringUtils.parseResource(from))) + { + Map userPresences; + if (!presenceMap.containsKey(key)) { + userPresences = new ConcurrentHashMap(); + presenceMap.put(key, userPresences); + } + else { + userPresences = presenceMap.get(key); + // Any other presence data is invalidated by the error packet. + userPresences.clear(); + } + // Set the new presence using the empty resource as a key. + userPresences.put("", presence); + // If the user is in the roster, fire an event. + RosterEntry entry = entries.get(key); + if (entry != null) { + fireRosterPresenceEvent(presence); + } + } } } @@ -852,4 +877,4 @@ public class Roster { fireRosterChangedEvent(addedEntries, updatedEntries, deletedEntries); } } -} \ No newline at end of file +} diff --git a/source/org/jivesoftware/smack/packet/Presence.java b/source/org/jivesoftware/smack/packet/Presence.java index 5e6941c3d..97402a005 100644 --- a/source/org/jivesoftware/smack/packet/Presence.java +++ b/source/org/jivesoftware/smack/packet/Presence.java @@ -92,7 +92,10 @@ public class Presence extends Packet { * Returns true if the {@link Type presence type} is available (online) and * false if the user is unavailable (offline), or if this is a presence packet * involved in a subscription operation. This is a convenience method - * equivalent to getType() == Presence.Type.available. + * equivalent to getType() == Presence.Type.available. Note that even + * when the user is available, their presence mode may be {@link Mode#away away}, + * {@link Mode#xa extended away} or {@link Mode#dnd do not disturb}. Use + * {@link #isAway()} to determine if the user is away. * * @return true if the presence type is available. */