aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl
diff options
context:
space:
mode:
authorDanny van Heumen <danny@dannyvanheumen.nl>2015-05-17 14:21:15 +0200
committerDanny van Heumen <danny@dannyvanheumen.nl>2015-05-30 20:10:21 +0200
commit0e810a59a365943ac76628256351e90bd77b6319 (patch)
treec257fa4b4979a3d9c89613cfab08d1e0b26d1557 /src/net/java/sip/communicator/impl
parent45626391be7a4f5b8b6d9e7bb8624fcbb9f62b2f (diff)
downloadjitsi-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.java45
-rw-r--r--src/net/java/sip/communicator/impl/protocol/irc/IrcConnection.java67
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;
+ }
+ }
+ }
}