diff options
author | Damian Minkov <damencho@jitsi.org> | 2012-06-19 14:24:22 +0000 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2012-06-19 14:24:22 +0000 |
commit | 161d186f5e7ca53b63bdb20c88101b863d9a3498 (patch) | |
tree | e083717663936d84283046881025575c7e01f40e /src/net/java | |
parent | 5d5788b116924f06343a68c73d70dab1579ca24c (diff) | |
download | jitsi-161d186f5e7ca53b63bdb20c88101b863d9a3498.zip jitsi-161d186f5e7ca53b63bdb20c88101b863d9a3498.tar.gz jitsi-161d186f5e7ca53b63bdb20c88101b863d9a3498.tar.bz2 |
Fixes handling away status after successful reconnection.
Fixes a problem in reconnect plugin where several reconnects can happen, after several reconnection retries.
Fixes reconnection after xmpp connection throws ConnectException or NoRouteToHostException.
Diffstat (limited to 'src/net/java')
5 files changed, 255 insertions, 52 deletions
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index 3b2953e..f306b85 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -905,7 +905,16 @@ public class ProtocolProviderServiceJabberImpl //socket could not be opened if (ex.getWrappedThrowable() instanceof ConnectException || ex.getWrappedThrowable() instanceof NoRouteToHostException) + { + //as we got an exception not handled in connectAndLogin + //no state was set, so fire it here so we can continue + //with the re-register process + fireRegistrationStateChanged(getRegistrationState(), + RegistrationState.CONNECTION_FAILED, + RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND, null); + throw ex; + } // don't attempt to append the service name if it's already there if (!qualifiedUserID) diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java index 4f945fc..c3dc2f5 100644 --- a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java +++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java @@ -369,8 +369,12 @@ public class SystemActivityNotificationsServiceImpl }
else if(idleTime != 0)
{
- long minIdleSetting =
- Collections.min(idleChangeListeners.values());
+ long minIdleSetting = CHECK_FOR_IDLE_DEFAULT;
+
+ if(!idleChangeListeners.isEmpty())
+ minIdleSetting =
+ Collections.min(idleChangeListeners.values());
+
int newSetting = (int)(minIdleSetting - idleTime) + 1000;
if(newSetting > 0)
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java index ec44875..38f6710 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java @@ -9,9 +9,11 @@ package net.java.sip.communicator.plugin.generalconfig.autoaway; import net.java.sip.communicator.plugin.generalconfig.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.sysactivity.*;
import net.java.sip.communicator.service.sysactivity.event.*;
import net.java.sip.communicator.util.*;
+import org.osgi.framework.*;
import java.beans.*;
import java.util.*;
@@ -21,15 +23,27 @@ import java.util.*; * @author Damian Minkov
*/
public class AutoAwayWatcher
- implements SystemActivityChangeListener
+ implements ServiceListener,
+ RegistrationStateChangeListener
{
/**
+ * The logger.
+ */
+ private static final Logger logger
+ = Logger.getLogger(AutoAwayWatcher.class);
+
+ /**
* The states of providers before going to away.
*/
private final Map<ProtocolProviderService, PresenceStatus> lastStates
= new HashMap<ProtocolProviderService, PresenceStatus>();
/**
+ * Listens for idle events.
+ */
+ private IdleListener idleListener = null;
+
+ /**
* Creates AutoAway handler.
* @param configurationService the config service.
*/
@@ -53,35 +67,73 @@ public class AutoAwayWatcher if(Boolean.parseBoolean((String)evt.getNewValue()))
start();
else
- stop();
+ stopInner();
}
}
);
// listens for changes in configured value.
configurationService.addPropertyChangeListener(
- Preferences.TIMER,
- new PropertyChangeListener()
+ Preferences.TIMER,
+ new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent evt)
{
- public void propertyChange(PropertyChangeEvent evt)
- {
- stop();
- start();
- }
+ stopInner();
+ start();
}
+ }
);
+
+ // listen for new providers
+ GeneralConfigPluginActivator.bundleContext.addServiceListener(this);
+
+ // lets check current providers
+ ServiceReference[] protocolProviderRefs = null;
+ try
+ {
+ protocolProviderRefs = GeneralConfigPluginActivator.bundleContext
+ .getServiceReferences(ProtocolProviderService.class.getName(),
+ null);
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ // this shouldn't happen since we're providing no parameter string
+ // but let's log just in case.
+ logger.error(
+ "Error while retrieving service refs", ex);
+ return;
+ }
+
+ // in case we found any
+ if (protocolProviderRefs != null)
+ {
+ for (int i = 0; i < protocolProviderRefs.length; i++)
+ {
+ ProtocolProviderService provider = (ProtocolProviderService)
+ GeneralConfigPluginActivator.bundleContext
+ .getService(protocolProviderRefs[i]);
+
+ this.handleProviderAdded(provider);
+ }
+ }
}
/**
* Starts and add needed listeners.
*/
- public void start()
+ private void start()
{
- getSystemActivityNotificationsService()
- .addIdleSystemChangeListener(
- StatusUpdateThread.getTimer()*60*1000, this);
- getSystemActivityNotificationsService()
- .addSystemActivityChangeListener(this);
+ if(idleListener == null)
+ {
+ idleListener = new IdleListener();
+
+ getSystemActivityNotificationsService()
+ .addIdleSystemChangeListener(
+ StatusUpdateThread.getTimer()*60*1000, idleListener);
+ getSystemActivityNotificationsService()
+ .addSystemActivityChangeListener(idleListener);
+ }
}
/**
@@ -89,34 +141,23 @@ public class AutoAwayWatcher */
public void stop()
{
- getSystemActivityNotificationsService()
- .removeIdleSystemChangeListener(this);
- getSystemActivityNotificationsService()
- .removeSystemActivityChangeListener(this);
+ GeneralConfigPluginActivator.bundleContext.removeServiceListener(this);
+ stopInner();
}
/**
- * Listens for activities and set corresponding statuses.
- *
- * @param event the <tt>NotificationActionTypeEvent</tt>, which is
+ * Stops and removes the listeners, without the global service listener.
*/
- public void activityChanged(SystemActivityEvent event)
+ private void stopInner()
{
- switch(event.getEventID())
- {
- case SystemActivityEvent.EVENT_DISPLAY_SLEEP:
- case SystemActivityEvent.EVENT_SCREEN_LOCKED:
- case SystemActivityEvent.EVENT_SCREENSAVER_START:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE:
- changeProtocolsToAway();
- break;
- case SystemActivityEvent.EVENT_DISPLAY_WAKE:
- case SystemActivityEvent.EVENT_SCREEN_UNLOCKED:
- case SystemActivityEvent.EVENT_SCREENSAVER_STOP:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
- changeProtocolsToPreviousState();
- break;
- }
+ if(idleListener == null)
+ return;
+
+ getSystemActivityNotificationsService()
+ .removeIdleSystemChangeListener(idleListener);
+ getSystemActivityNotificationsService()
+ .removeSystemActivityChangeListener(idleListener);
+ idleListener = null;
}
/**
@@ -126,7 +167,7 @@ public class AutoAwayWatcher private void changeProtocolsToAway()
{
for (ProtocolProviderService protocolProviderService
- : GeneralConfigPluginActivator.getProtocolProviders())
+ : GeneralConfigPluginActivator.getProtocolProviders())
{
OperationSetPresence presence
= protocolProviderService
@@ -143,7 +184,7 @@ public class AutoAwayWatcher continue;
}
- lastStates.put(protocolProviderService, status);
+ addProviderToLastStates(protocolProviderService, status);
PresenceStatus newStatus =
StatusUpdateThread.findAwayStatus(presence);
@@ -173,14 +214,15 @@ public class AutoAwayWatcher for (ProtocolProviderService protocolProviderService
: GeneralConfigPluginActivator.getProtocolProviders())
{
- if (lastStates.get(protocolProviderService) != null)
+ PresenceStatus lastState
+ = lastStates.get(protocolProviderService);
+
+ if (lastState != null)
{
- PresenceStatus lastState
- = lastStates.get(protocolProviderService);
OperationSetPresence presence
= protocolProviderService
.getOperationSet(
- OperationSetPresence.class);
+ OperationSetPresence.class);
try
{
presence
@@ -192,7 +234,7 @@ public class AutoAwayWatcher } catch (OperationFailedException e)
{
}
- lastStates.remove(protocolProviderService);
+ removeProviderFromLastStates(protocolProviderService);
}
}
}
@@ -208,4 +250,143 @@ public class AutoAwayWatcher GeneralConfigPluginActivator.bundleContext,
SystemActivityNotificationsService.class);
}
+
+ /**
+ * When new protocol provider is registered we add our
+ * registration change listener.
+ * If unregistered remove reference to the provider and the
+ * registration change listener.
+ *
+ * @param serviceEvent ServiceEvent
+ */
+ public void serviceChanged(ServiceEvent serviceEvent)
+ {
+ Object sService = GeneralConfigPluginActivator.bundleContext
+ .getService(serviceEvent.getServiceReference());
+
+ // we don't care if the source service is not a protocol provider
+ if (! (sService instanceof ProtocolProviderService))
+ {
+ return;
+ }
+
+ if (serviceEvent.getType() == ServiceEvent.REGISTERED)
+ {
+ this.handleProviderAdded((ProtocolProviderService)sService);
+ }
+ else if (serviceEvent.getType() == ServiceEvent.UNREGISTERING)
+ {
+ this.handleProviderRemoved( (ProtocolProviderService) sService);
+ }
+ }
+
+ /**
+ * Used to set registration state change listener.
+ *
+ * @param provider ProtocolProviderService
+ */
+ private synchronized void handleProviderAdded(
+ ProtocolProviderService provider)
+ {
+ provider.addRegistrationStateChangeListener(this);
+ }
+
+ /**
+ * Removes the registration change listener.
+ *
+ * @param provider the ProtocolProviderService that has been unregistered.
+ */
+ private void handleProviderRemoved(ProtocolProviderService provider)
+ {
+ provider.removeRegistrationStateChangeListener(this);
+ }
+
+ /**
+ * Remove provider from list with last statuses.
+ * If this is the last provider stop listening for idle events.
+ * @param provider
+ */
+ private synchronized void removeProviderFromLastStates(
+ ProtocolProviderService provider)
+ {
+ lastStates.remove(provider);
+
+ if(lastStates.size() == 0)
+ {
+ stopInner();
+ }
+ }
+
+ /**
+ * Remember provider's last status, normally before setting it to away.
+ * If needed start listening for idle events.
+ * @param provider the provider.
+ * @param status the status to save.
+ */
+ private synchronized void addProviderToLastStates(
+ ProtocolProviderService provider, PresenceStatus status)
+ {
+ if(lastStates.size() == 0)
+ {
+ start();
+ }
+
+ lastStates.put(provider, status);
+ }
+
+ /**
+ * Listens for provider states.
+ * @param evt
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ if(evt.getSource() instanceof ProtocolProviderService)
+ {
+ if(evt.getNewState().equals(RegistrationState.UNREGISTERED)
+ || evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
+ {
+ removeProviderFromLastStates(evt.getProvider());
+ }
+ else if(evt.getNewState().equals(
+ RegistrationState.REGISTERED))
+ {
+ // we have at least one provider, so lets start listening
+ if(lastStates.size() == 0)
+ {
+ start();
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener waiting for idle state change.
+ */
+ private class IdleListener
+ implements SystemActivityChangeListener
+ {
+ /**
+ * Listens for activities and set corresponding statuses.
+ *
+ * @param event the <tt>NotificationActionTypeEvent</tt>, which is
+ */
+ public void activityChanged(SystemActivityEvent event)
+ {
+ switch(event.getEventID())
+ {
+ case SystemActivityEvent.EVENT_DISPLAY_SLEEP:
+ case SystemActivityEvent.EVENT_SCREEN_LOCKED:
+ case SystemActivityEvent.EVENT_SCREENSAVER_START:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE:
+ changeProtocolsToAway();
+ break;
+ case SystemActivityEvent.EVENT_DISPLAY_WAKE:
+ case SystemActivityEvent.EVENT_SCREEN_UNLOCKED:
+ case SystemActivityEvent.EVENT_SCREENSAVER_STOP:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
+ changeProtocolsToPreviousState();
+ break;
+ }
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf b/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf index 91d7c24..e5741a7 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf @@ -9,6 +9,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.resources, diff --git a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java index a4ee972..3fa83c1 100644 --- a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java +++ b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java @@ -553,13 +553,17 @@ public class ReconnectPluginActivator if(timer == null || task == null) return; - currentlyReconnecting.put(pp, task); + // cancel any existing task before overriding it + if(currentlyReconnecting.containsKey(pp)) + currentlyReconnecting.remove(pp).cancel(); - if (logger.isTraceEnabled()) - logger.trace("Reconnect " + pp + - " after " + task.delay + " ms."); + currentlyReconnecting.put(pp, task); - timer.schedule(task, task.delay); + if (logger.isTraceEnabled()) + logger.trace("Reconnect " + pp + + " after " + task.delay + " ms."); + + timer.schedule(task, task.delay); } return; } @@ -801,6 +805,10 @@ public class ReconnectPluginActivator return; } + // cancel any existing task before overriding it + if(currentlyReconnecting.containsKey(pp)) + currentlyReconnecting.remove(pp).cancel(); + currentlyReconnecting.put(pp, task); if (logger.isTraceEnabled()) |