diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java index a454dda77..5b31a82ba 100644 --- a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java +++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java @@ -450,7 +450,7 @@ else if (itemName.equals(GlobalStatusEnum.OFFLINE_STATUS)) try { - protocolProvider.unregister(); + protocolProvider.unregister(true); } catch (OperationFailedException e1) { 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 3f185bebe..cee60935e 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -561,7 +561,7 @@ void reregister(int authReasonCode) // sets this if any is trying to use us through registration // to know we are not registered - this.unregister(false); + this.unregisterInternal(false); // reset states this.abortConnecting = false; @@ -1505,14 +1505,32 @@ public void disconnectAndCleanConnection() */ public void unregister() { - unregister(true); + unregisterInternal(true); + } + + /** + * Ends the registration of this protocol provider with the service. + * @param userRequest is the unregister by user request. + */ + public void unregister(boolean userRequest) + { + unregisterInternal(true, userRequest); + } + + /** + * Unregister and fire the event if requested + * @param fireEvent boolean + */ + public void unregisterInternal(boolean fireEvent) + { + unregisterInternal(fireEvent, false); } /** * Unregister and fire the event if requested * @param fireEvent boolean */ - public void unregister(boolean fireEvent) + public void unregisterInternal(boolean fireEvent, boolean userRequest) { synchronized(initializationLock) { @@ -1523,7 +1541,8 @@ public void unregister(boolean fireEvent) getRegistrationState() , RegistrationState.UNREGISTERING , RegistrationStateChangeEvent.REASON_NOT_SPECIFIED - , null); + , null + , userRequest); } disconnectAndCleanConnection(); @@ -1536,7 +1555,8 @@ public void unregister(boolean fireEvent) fireRegistrationStateChanged( currRegState, RegistrationState.UNREGISTERED, - RegistrationStateChangeEvent.REASON_USER_REQUEST, null); + RegistrationStateChangeEvent.REASON_USER_REQUEST, null, + userRequest); } } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/keepalive/KeepAliveManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/keepalive/KeepAliveManager.java index fdc5350e8..9a4bef02c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/keepalive/KeepAliveManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/keepalive/KeepAliveManager.java @@ -225,7 +225,7 @@ public void run() +"won't send keep alive for " + parentProvider.getAccountID().getDisplayName()); - parentProvider.unregister(false); + parentProvider.unregisterInternal(false); parentProvider.fireRegistrationStateChanged( parentProvider.getRegistrationState(), @@ -244,7 +244,7 @@ public void run() logger.error("un-registering not received ping packet " + "for: " + parentProvider.getAccountID().getDisplayName()); - parentProvider.unregister(false); + parentProvider.unregisterInternal(false); parentProvider.fireRegistrationStateChanged( parentProvider.getRegistrationState(), diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java index dac258e0f..06f1d5d54 100644 --- a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java +++ b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java @@ -241,6 +241,15 @@ public void unregister() { } + /** + * Mock implementation of the corresponding ProtocolProviderService method. + */ + public void unregister(boolean userRequest) + throws OperationFailedException + { + this.unregister(); + } + /* * (non-Javadoc) * diff --git a/src/net/java/sip/communicator/impl/protocol/msn/EventManager.java b/src/net/java/sip/communicator/impl/protocol/msn/EventManager.java index e7ab7b509..646be8a38 100644 --- a/src/net/java/sip/communicator/impl/protocol/msn/EventManager.java +++ b/src/net/java/sip/communicator/impl/protocol/msn/EventManager.java @@ -191,7 +191,7 @@ public void run() { if(!connected && msnProvider.isRegistered()) { - msnProvider.unregister(false); + msnProvider.unregisterInternal(false); msnProvider.fireRegistrationStateChanged( msnProvider.getRegistrationState(), RegistrationState.CONNECTION_FAILED, diff --git a/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java b/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java index 813fda916..9b8d1e931 100644 --- a/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java @@ -246,7 +246,7 @@ private void connectAndLogin(SecurityAuthority authority, int reasonCode) */ public void unregister() { - unregister(true); + unregisterInternal(true); } /* @@ -275,7 +275,7 @@ public TransportProtocol getTransportProtocol() * Unregister and fire the event if requested * @param fireEvent boolean */ - void unregister(boolean fireEvent) + void unregisterInternal(boolean fireEvent) { RegistrationState currRegState = getRegistrationState(); @@ -393,7 +393,7 @@ public void shutdown() { synchronized(initializationLock) { - unregister(false); + unregisterInternal(false); messenger = null; } } @@ -479,7 +479,7 @@ public void logout(MsnMessenger msnMessenger) synchronized (initializationLock) { logoutReceived = true; - unregister(true); + unregisterInternal(true); } } @@ -493,7 +493,7 @@ public void exceptionCaught(MsnMessenger msnMessenger, { if(throwable instanceof IncorrectPasswordException) { - unregister(false); + unregisterInternal(false); MsnActivator.getProtocolProviderFactory(). storePassword(getAccountID(), null); @@ -538,7 +538,7 @@ else if(throwable instanceof MsnProtocolException) case 601: if(isRegistered()) { - unregister(false); + unregisterInternal(false); fireRegistrationStateChanged( getRegistrationState(), RegistrationState.UNREGISTERED, @@ -549,7 +549,7 @@ else if(throwable instanceof MsnProtocolException) case 911: if(isRegistered()) { - unregister(false); + unregisterInternal(false); MsnActivator.getProtocolProviderFactory(). storePassword(getAccountID(), null); fireRegistrationStateChanged( diff --git a/src/net/java/sip/communicator/impl/protocol/msn/ServerStoredContactListMsnImpl.java b/src/net/java/sip/communicator/impl/protocol/msn/ServerStoredContactListMsnImpl.java index 59fe6f2ed..bbae5be3c 100644 --- a/src/net/java/sip/communicator/impl/protocol/msn/ServerStoredContactListMsnImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/msn/ServerStoredContactListMsnImpl.java @@ -1303,7 +1303,7 @@ public void groupRenamed(MsnGroup group) @Override public void loggingFromOtherLocation() { - msnProvider.unregister(false); + msnProvider.unregisterInternal(false); msnProvider.fireRegistrationStateChanged( msnProvider.getRegistrationState(), RegistrationState.UNREGISTERED, diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java index 7877a7cb5..da36c7cbd 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -365,6 +365,20 @@ public void register(SecurityAuthority authority) */ public void unregister() throws OperationFailedException + { + unregister(false); + } + + /** + * Ends the registration of this protocol provider with the current + * registration service. + * + * @throws OperationFailedException with the corresponding code it the + * registration fails for some reason (e.g. a networking error or an + * implementation problem). + */ + public void unregister(boolean userRequest) + throws OperationFailedException { if(getRegistrationState().equals(RegistrationState.UNREGISTERED) || getRegistrationState().equals(RegistrationState.UNREGISTERING) @@ -373,7 +387,7 @@ public void unregister() return; } - sipRegistrarConnection.unregister(); + sipRegistrarConnection.unregister(userRequest); sipSecurityManager.setSecurityAuthority(null); } diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipApplicationData.java b/src/net/java/sip/communicator/impl/protocol/sip/SipApplicationData.java index 27e48ade4..f516ccc69 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipApplicationData.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipApplicationData.java @@ -36,6 +36,11 @@ public class SipApplicationData */ public static final String KEY_SUBSCRIPTIONS = "subscriptions"; + /** + * Key user request. + */ + public static final String KEY_USER_REQUEST = "userRequest"; + /** * Logger for this class. */ diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java index 145ef6d1a..7408dcd16 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java @@ -425,9 +425,18 @@ public void processOK(ClientTransaction clientTransatcion, logger.debug("Account " + sipProvider.getAccountID().getDisplayName() + " unregistered!"); + + Boolean userRequest = (Boolean)SipApplicationData.getApplicationData( + register, SipApplicationData.KEY_USER_REQUEST); + + boolean userRequestBool = false; + if(userRequest != null && userRequest) + userRequestBool = true; + setRegistrationState(RegistrationState.UNREGISTERED , RegistrationStateChangeEvent.REASON_USER_REQUEST - , "Registration terminated."); + , "Registration terminated.", + userRequestBool); } else { @@ -518,7 +527,19 @@ public boolean isRequestFromSameConnection(Request request) */ public void unregister() throws OperationFailedException { - unregister(true); + unregisterInternal(true, false); + } + + /** + * Sends a unregistered request to the registrar thus ending our + * registration. + * @throws OperationFailedException with the corresponding code if sending + * or constructing the request fails. + */ + public void unregister(boolean userRequest) + throws OperationFailedException + { + unregisterInternal(true, userRequest); } /** @@ -531,7 +552,7 @@ public void unregister() throws OperationFailedException * @throws OperationFailedException with the corresponding code if sending * or constructing the request fails. */ - private void unregister(boolean sendUnregister) + private void unregisterInternal(boolean sendUnregister, boolean userRequest) throws OperationFailedException { if (getRegistrationState() == RegistrationState.UNREGISTERED) @@ -581,6 +602,12 @@ private void unregister(boolean sendUnregister) , ex); } + if(userRequest) + { + SipApplicationData.setApplicationData(unregisterRequest, + SipApplicationData.KEY_USER_REQUEST, userRequest); + } + ClientTransaction unregisterTransaction = null; try { @@ -669,6 +696,24 @@ public RegistrationState getRegistrationState() public void setRegistrationState(RegistrationState newState, int reasonCode, String reason) + { + this.setRegistrationState(newState, reasonCode, reason, false); + } + + /** + * Sets our registration state to newState and dispatches an event + * through the protocol provider service impl. + *
+ * @param newState a reference to the RegistrationState that we're currently + * detaining. + * @param reasonCode one of the REASON_XXX error codes specified in + * {@link RegistrationStateChangeEvent}. + * @param reason a reason String further explaining the reasonCode. + */ + public void setRegistrationState(RegistrationState newState, + int reasonCode, + String reason, + boolean userRequest) { if( currentRegistrationState.equals(newState) ) return; @@ -677,7 +722,7 @@ public void setRegistrationState(RegistrationState newState, this.currentRegistrationState = newState; sipProvider.fireRegistrationStateChanged( - oldState, newState, reasonCode, reason); + oldState, newState, reasonCode, reason, userRequest); } /** diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java index 417e5befe..7bf9fc45c 100644 --- a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java @@ -289,14 +289,14 @@ void reregister(int reasonCode) */ public void unregister() { - unregister(true); + unregisterInternal(true); } /** * Unregister and fire the event if requested * @param fireEvent boolean */ - void unregister(boolean fireEvent) + void unregisterInternal(boolean fireEvent) { RegistrationState currRegState = getRegistrationState(); @@ -437,7 +437,7 @@ protected void initialize(String screenname, public void shutdown() { synchronized(initializationLock){ - unregister(false); + unregisterInternal(false); yahooSession = null; isInitialized = false; } @@ -496,7 +496,7 @@ public void fireRegistrationStateChanged( RegistrationState oldState, { if(newState.equals(RegistrationState.UNREGISTERED)) { - unregister(false); + unregisterInternal(false); yahooSession = null; } @@ -543,7 +543,7 @@ public void inputExceptionThrown(SessionExceptionEvent ev) logger.error( "Yahoo protocol exception occured", ev.getException()); - unregister(false); + unregisterInternal(false); if(isRegistered()) fireRegistrationStateChanged( getRegistrationState(), diff --git a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java index 1ce59dae9..8e63cdb09 100644 --- a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java +++ b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java @@ -775,7 +775,10 @@ else if(evt.getNewState().equals(RegistrationState.REGISTERED)) } else if(evt.getNewState().equals(RegistrationState.UNREGISTERED)) { - autoReconnEnabledProviders.remove(pp); + // Removes from list of autoreconnect only if the unregister + // event is by user request + if(evt.isUserRequest()) + autoReconnEnabledProviders.remove(pp); if(!unregisteringProviders.contains(pp) && currentlyReconnecting.containsKey(pp)) diff --git a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java index 7053d6774..921802825 100644 --- a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java +++ b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java @@ -126,10 +126,35 @@ public void fireRegistrationStateChanged( RegistrationState oldState, RegistrationState newState, int reasonCode, String reason) + { + this.fireRegistrationStateChanged( + oldState, newState, reasonCode, reason, false); + } + + /** + * Creates a RegistrationStateChange event corresponding to the specified + * old and new states and notifies all currently registered listeners. + * + * @param oldState the state that the provider had before the change + * occurred + * @param newState the state that the provider is currently in. + * @param reasonCode a value corresponding to one of the REASON_XXX fields + * of the RegistrationStateChangeEvent class, indicating the reason for + * this state transition. + * @param reason a String further explaining the reason code or null if + * no such explanation is necessary. + * @param userRequest is the event by user request. + */ + public void fireRegistrationStateChanged( RegistrationState oldState, + RegistrationState newState, + int reasonCode, + String reason, + boolean userRequest) { RegistrationStateChangeEvent event = new RegistrationStateChangeEvent( this, oldState, newState, reasonCode, reason); + event.setUserRequest(userRequest); RegistrationStateChangeListener[] listeners; synchronized (registrationListeners) @@ -316,4 +341,20 @@ public String toString() return getClass().getSimpleName() + "(" + getAccountID().getDisplayName() + ")"; } + + /** + * Ends the registration of this protocol provider with the current + * registration service. The default is just to call unregister. Providers + * that need to differentiate user requests (from the UI) or automatic + * unregister can override this method. + * @param userRequest is the unregister by user request. + * @throws OperationFailedException with the corresponding code it the + * registration fails for some reason (e.g. a networking error or an + * implementation problem). + */ + public void unregister(boolean userRequest) + throws OperationFailedException + { + this.unregister(); + } } diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java index 5bd182ba0..58594f62d 100644 --- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java +++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java @@ -74,6 +74,17 @@ public void register(SecurityAuthority authority) public void unregister() throws OperationFailedException; + /** + * Ends the registration of this protocol provider with the current + * registration service. + * @param userRequest is the unregister by user request. + * @throws OperationFailedException with the corresponding code it the + * registration fails for some reason (e.g. a networking error or an + * implementation problem). + */ + public void unregister(boolean userRequest) + throws OperationFailedException; + /** * Indicates whether or not this provider is registered * @return true if the provider is currently registered and false otherwise. diff --git a/src/net/java/sip/communicator/service/protocol/event/RegistrationStateChangeEvent.java b/src/net/java/sip/communicator/service/protocol/event/RegistrationStateChangeEvent.java index dc1cb20ec..6df601ebb 100644 --- a/src/net/java/sip/communicator/service/protocol/event/RegistrationStateChangeEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/RegistrationStateChangeEvent.java @@ -110,6 +110,11 @@ public class RegistrationStateChangeEvent extends PropertyChangeEvent */ private final String reason; + /** + * Whether this event is after user request. + */ + private boolean userRequest = false; + /** * Creates an event instance indicating a change of the provider state * from oldValue to newValue. @@ -211,4 +216,22 @@ public String getReason() { return reason; } + + /** + * Whether this event is after user request. + * @return whether this event is after user request. + */ + public boolean isUserRequest() + { + return userRequest; + } + + /** + * Changes the event to indicate that is created after use request. + * @param userRequest + */ + public void setUserRequest(boolean userRequest) + { + this.userRequest = userRequest; + } } diff --git a/src/net/java/sip/communicator/util/account/LoginManager.java b/src/net/java/sip/communicator/util/account/LoginManager.java index aea9b6c81..a2ad4138e 100644 --- a/src/net/java/sip/communicator/util/account/LoginManager.java +++ b/src/net/java/sip/communicator/util/account/LoginManager.java @@ -547,7 +547,7 @@ public void run() { try { - protocolProvider.unregister(); + protocolProvider.unregister(true); } catch (OperationFailedException ex) {