diff options
author | Danny van Heumen <danny@dannyvanheumen.nl> | 2015-05-17 14:21:15 +0200 |
---|---|---|
committer | Danny van Heumen <danny@dannyvanheumen.nl> | 2015-05-30 20:10:21 +0200 |
commit | 0e810a59a365943ac76628256351e90bd77b6319 (patch) | |
tree | c257fa4b4979a3d9c89613cfab08d1e0b26d1557 /src/net/java/sip/communicator/impl | |
parent | 45626391be7a4f5b8b6d9e7bb8624fcbb9f62b2f (diff) | |
download | jitsi-0e810a59a365943ac76628256351e90bd77b6319.zip jitsi-0e810a59a365943ac76628256351e90bd77b6319.tar.gz jitsi-0e810a59a365943ac76628256351e90bd77b6319.tar.bz2 |
Partial support for IRC away notifications.
Implemented state management for away notify capability. Now only
missing the handling of AWAY messages that are sent by the IRC server
when away-notify is active.
Diffstat (limited to 'src/net/java/sip/communicator/impl')
-rw-r--r-- | src/net/java/sip/communicator/impl/protocol/irc/ChannelManager.java | 45 | ||||
-rw-r--r-- | src/net/java/sip/communicator/impl/protocol/irc/IrcConnection.java | 67 |
2 files changed, 92 insertions, 20 deletions
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ChannelManager.java b/src/net/java/sip/communicator/impl/protocol/irc/ChannelManager.java index a59ed48..a4e141f 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/ChannelManager.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/ChannelManager.java @@ -104,6 +104,11 @@ public class ChannelManager = new HashMap<Character, Integer>(); /** + * Flag for indicating availability of Away Notify capability. + */ + private final boolean awayNotify; + + /** * Constructor. * * @param irc thread-safe IRCApi instance @@ -113,7 +118,7 @@ public class ChannelManager */ public ChannelManager(final IRCApi irc, final IIRCState connectionState, final ProtocolProviderServiceIrcImpl provider, - final ClientConfig config) + final ClientConfig config, final boolean awayNotifyCapability) { if (irc == null) { @@ -146,6 +151,7 @@ public class ChannelManager this.isupportKickLen = parseISupportInteger(this.connectionState, ISupport.KICKLEN); parseISupportChanLimit(this.isupportChanLimit, this.connectionState); + this.awayNotify = awayNotifyCapability; } /** @@ -356,7 +362,8 @@ public class ChannelManager ChannelManager.this.irc .addListener(new ChatRoomListener(chatroom, ChannelManager.this.config - .isChannelPresenceTaskEnabled())); + .isChannelPresenceTaskEnabled(), + ChannelManager.this.awayNotify)); prepareChatRoom(chatroom, channel); } finally @@ -755,7 +762,8 @@ public class ChannelManager ChannelManager.this.joined.put(channelName, chatRoom); } this.irc.addListener(new ChatRoomListener(chatRoom, - ChannelManager.this.config.isChannelPresenceTaskEnabled())); + ChannelManager.this.config.isChannelPresenceTaskEnabled(), + ChannelManager.this.awayNotify)); try { ChannelManager.this.provider.getMUC().openChatRoomWindow( @@ -787,6 +795,8 @@ public class ChannelManager * chat room listener updates chat room data and fires events based on IRC * messages that report state changes for the specified channel. * + * FIXME handle AWAY messages (from away-notify) for fellow channel members + * * @author Danny van Heumen */ private final class ChatRoomListener @@ -820,14 +830,18 @@ public class ChannelManager private static final int IRC_RPL_ENDOFWHO = 315; /** - * Presence task initial delay. + * Presence task period. */ - private static final long TASK_INITIAL_DELAY = 1000L; + private static final long TASK_PERIOD = 60000L; /** - * Presence task period. + * Presence task initial delay. + * + * The first WHO-request is fired during ChatRoomListener constructions, + * as we need at least 1 such request, even if away-notify capability is + * active. */ - private static final long TASK_PERIOD = 60000L; + private static final long TASK_INITIAL_DELAY = TASK_PERIOD; /** * Chat room for which this listener is working. @@ -843,9 +857,15 @@ public class ChannelManager * Constructor. Instantiate listener for the provided chat room. * * @param chatroom the chat room + * @param activatePresenceWatcher flag indicating whether or not to + * activate the periodic presence watcher task + * @param awayNotifyCapability flag indicating whether or not away + * notifications are active. If they are active, there is no + * need to periodically query presence status. */ private ChatRoomListener(final ChatRoomIrcImpl chatroom, - final boolean activatePresenceWatcher) + final boolean activatePresenceWatcher, + final boolean awayNotifyCapability) { super(ChannelManager.this.irc, ChannelManager.this.connectionState); if (chatroom == null) @@ -853,10 +873,17 @@ public class ChannelManager throw new IllegalArgumentException("chatroom cannot be null"); } this.chatroom = chatroom; - if (activatePresenceWatcher) + if (activatePresenceWatcher && !awayNotifyCapability) { createPeriodicPresenceWatcher(); } + else + { + LOGGER.info("Not activating periodic presence watcher. " + + "(away-notify capability is " + awayNotifyCapability + + ")"); + } + this.irc.rawMessage("WHO " + chatroom.getIdentifier()); } /** diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcConnection.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcConnection.java index c0bdb80..8b7c013 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/IrcConnection.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcConnection.java @@ -18,6 +18,8 @@ import com.ircclouds.irc.api.*; import com.ircclouds.irc.api.domain.messages.*; import com.ircclouds.irc.api.listeners.*; import com.ircclouds.irc.api.negotiators.*; +import com.ircclouds.irc.api.negotiators.CompositeNegotiator.Capability; +import com.ircclouds.irc.api.negotiators.capabilities.*; import com.ircclouds.irc.api.state.*; /** @@ -149,10 +151,12 @@ public class IrcConnection // Prepare an IRC capability negotiator in case version 3 is allowed. final CapabilityNegotiator negotiator; + final NegotiationHandler handler = new NegotiationHandler(); if (config.isVersion3Allowed()) { negotiator = - determineNegotiator(params.getNickname(), password, config); + determineNegotiator(params.getNickname(), password, config, + handler); } else { @@ -181,7 +185,7 @@ public class IrcConnection // instantiate channel manager for the connection this.channel = new ChannelManager(this.irc, this.connectionState, - this.context.provider, this.config); + this.context.provider, this.config, handler.awayNotify); // instantiate presence manager for the connection this.presence = @@ -208,22 +212,22 @@ public class IrcConnection * * @param user the user nick used for authentication * @param password the authentication password + * @param config the client configuration + * @param handler the negotiation handler for updates during negotiation * @return returns capability negotiator */ private static CapabilityNegotiator determineNegotiator(final String user, - final String password, final ClientConfig config) + final String password, final ClientConfig config, + final CompositeNegotiator.Host handler) { + final ArrayList<Capability> capabilities = new ArrayList<Capability>(); + capabilities.add(new SimpleCapability("away-notify")); final SASL sasl = config.getSASL(); - if (sasl == null) + if (sasl != null) { - return new NoopNegotiator(); + capabilities.add(new SaslCapability(true, sasl.getRole(), sasl.getUser(), sasl.getPass())); } - // TODO In time, replace SaslNegotiator with CompositeNegotiator and - // SaslCapability together with any supported other capabilities. - // 'away-notify' would be an interesting option, so we do not have to - // periodically query channel status. - return new SaslNegotiator(sasl.getUser(), sasl.getPass(), - sasl.getRole()); + return new CompositeNegotiator(capabilities, handler); } /** @@ -232,6 +236,7 @@ public class IrcConnection * @param provider Parent protocol provider * @param params Server connection parameters * @param irc IRC Api instance + * @param negotiator the capability negotiator for enabling IRCv3 features * @throws Exception exception thrown when connect fails */ private static IIRCState connectSynchronized( @@ -511,4 +516,44 @@ public class IrcConnection } } } + + /** + * Capability negotiation handler. + * + * This handler receives the negotiation results for each capability as soon + * as it is known. This class is used to get an update on what capabilities + * are available to the client. + * + * @author Danny van Heumen + */ + private static class NegotiationHandler implements CompositeNegotiator.Host { + + /** + * Constant for id of away notify capability. + */ + private static final String AWAY_NOTIFY = "away-notify"; + + /** + * Availability of 'away-notify' capability. + */ + private boolean awayNotify = false; + + @Override + public void acknowledge(Capability cap) + { + LOGGER.info("Capability " + cap.getId() + " acknowledged."); + if (AWAY_NOTIFY.equals(cap.getId())) { + this.awayNotify = true; + } + } + + @Override + public void reject(Capability cap) + { + LOGGER.info("Capability " + cap.getId() + " rejected."); + if (AWAY_NOTIFY.equals(cap.getId())) { + this.awayNotify = false; + } + } + } } |