diff --git a/lib/installer-exclude/libjitsi.jar b/lib/installer-exclude/libjitsi.jar index 7fe944931..78935199c 100644 Binary files a/lib/installer-exclude/libjitsi.jar and b/lib/installer-exclude/libjitsi.jar differ diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java index 0c5c78d2d..55dc3df84 100644 --- a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java +++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java @@ -7,7 +7,9 @@ package net.java.sip.communicator.impl.globaldisplaydetails; import net.java.sip.communicator.service.globaldisplaydetails.*; +import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.globalstatus.*; import net.java.sip.communicator.util.*; import org.jitsi.service.configuration.*; @@ -37,6 +39,16 @@ public class GlobalDisplayDetailsActivator */ private static ConfigurationService configService; + /** + * The alert UI service. + */ + private static AlertUIService alertUIService; + + /** + * The UI service. + */ + private static UIService uiService; + /** * The display details implementation. */ @@ -61,6 +73,11 @@ public void start(BundleContext bc) GlobalDisplayDetailsService.class.getName(), displayDetailsImpl, null); + + bundleContext.registerService( + GlobalStatusService.class.getName(), + new GlobalStatusServiceImpl(), + null); } /** @@ -111,6 +128,42 @@ public static ConfigurationService getConfigurationService() return configService; } + /** + * Returns the AlertUIService obtained from the bundle + * context. + * @return the AlertUIService obtained from the bundle + * context + */ + public static AlertUIService getAlertUIService() + { + if(alertUIService == null) + { + alertUIService + = ServiceUtils.getService( + bundleContext, + AlertUIService.class); + } + return alertUIService; + } + + /** + * Returns the UIService obtained from the bundle + * context. + * @return the UIService obtained from the bundle + * context + */ + public static UIService getUIService() + { + if(uiService == null) + { + uiService + = ServiceUtils.getService( + bundleContext, + UIService.class); + } + return uiService; + } + /** * Implements the ServiceListener method. Verifies whether the * passed event concerns a ProtocolProviderService and adds or diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusServiceImpl.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java similarity index 71% rename from src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusServiceImpl.java rename to src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java index eb09a41b7..616c200de 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusServiceImpl.java +++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java @@ -3,10 +3,8 @@ * * Distributable under LGPL license. See terms of license at gnu.org. */ -package net.java.sip.communicator.impl.gui.main.presence; +package net.java.sip.communicator.impl.globaldisplaydetails; -import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.globalstatus.*; import net.java.sip.communicator.util.*; @@ -45,6 +43,8 @@ public PresenceStatus getLastPresenceStatus( { String lastStatus = getLastStatusString(protocolProvider); + PresenceStatus status = null; + if (lastStatus != null) { OperationSetPresence presence @@ -54,16 +54,62 @@ public PresenceStatus getLastPresenceStatus( return null; Iterator i = presence.getSupportedStatusSet(); - PresenceStatus status; + // Check if there's such status in the supported presence status + // set. while (i.hasNext()) { - status = i.next(); - if (status.getStatusName().equals(lastStatus)) - return status; + PresenceStatus nextStatus = i.next(); + + if (nextStatus.getStatusName().equals(lastStatus)) + status = nextStatus; + } + + // If we haven't found the last status in the protocol provider + // supported status set, we'll have a look for a corresponding + // global status and its protocol representation. + if (status == null) + { + if (lastStatus.equals(GlobalStatusEnum.ONLINE_STATUS)) + { + status = getPresenceStatus( + protocolProvider, + PresenceStatus.AVAILABLE_THRESHOLD, + PresenceStatus.EAGER_TO_COMMUNICATE_THRESHOLD); + } + else if (lastStatus.equals(GlobalStatusEnum.AWAY_STATUS)) + { + status = getPresenceStatus( + protocolProvider, + PresenceStatus.AWAY_THRESHOLD, + PresenceStatus.AVAILABLE_THRESHOLD); + } + else if (lastStatus + .equals(GlobalStatusEnum.DO_NOT_DISTURB_STATUS)) + { + status = getPresenceStatus( + protocolProvider, + PresenceStatus.ONLINE_THRESHOLD, + PresenceStatus.AWAY_THRESHOLD); + } + else if (lastStatus + .equals(GlobalStatusEnum.FREE_FOR_CHAT_STATUS)) + { + status = getPresenceStatus( + protocolProvider, + PresenceStatus.AVAILABLE_THRESHOLD, + PresenceStatus.MAX_STATUS_VALUE); + } + else if (lastStatus.equals(GlobalStatusEnum.OFFLINE_STATUS)) + { + status = getPresenceStatus( + protocolProvider, + 0, + GlobalStatusEnum.ONLINE_THRESHOLD); + } } } - return null; + return status; } /** @@ -79,7 +125,7 @@ public String getLastStatusString(ProtocolProviderService protocolProvider) String lastStatus = null; ConfigurationService configService - = GuiActivator.getConfigurationService(); + = GlobalDisplayDetailsActivator.getConfigurationService(); String prefix = "net.java.sip.communicator.impl.gui.accounts"; List accounts = configService.getPropertyNamesByPrefix(prefix, true); @@ -121,7 +167,7 @@ public void publishStatus( = protocolProvider.getOperationSet(OperationSetPresence.class); LoginManager loginManager - = GuiActivator.getUIService().getLoginManager(); + = GlobalDisplayDetailsActivator.getUIService().getLoginManager(); RegistrationState registrationState = protocolProvider.getRegistrationState(); @@ -147,7 +193,7 @@ else if (registrationState != RegistrationState.REGISTERED && registrationState != RegistrationState.AUTHENTICATING && status.isOnline()) { - GuiActivator.getUIService().getLoginManager() + GlobalDisplayDetailsActivator.getUIService().getLoginManager() .login(protocolProvider); } else if (!status.isOnline() @@ -176,12 +222,11 @@ public void publishStatus(GlobalStatusEnum globalStatus) String itemName = globalStatus.getStatusName(); Iterator pProviders - = GuiActivator.getUIService().getMainFrame().getProtocolProviders(); + = AccountUtils.getRegisteredProviders().iterator(); while (pProviders.hasNext()) { - ProtocolProviderService protocolProvider - = pProviders.next(); + ProtocolProviderService protocolProvider = pProviders.next(); if(itemName.equals(GlobalStatusEnum.ONLINE_STATUS)) { @@ -189,8 +234,8 @@ public void publishStatus(GlobalStatusEnum globalStatus) { saveStatusInformation(protocolProvider, itemName); - GuiActivator.getUIService().getLoginManager() - .login(protocolProvider); + GlobalDisplayDetailsActivator.getUIService() + .getLoginManager().login(protocolProvider); } else { @@ -282,27 +327,51 @@ else if (itemName.equals(GlobalStatusEnum.OFFLINE_STATUS)) } else if (itemName.equals(GlobalStatusEnum.FREE_FOR_CHAT_STATUS)) { - // we search for highest available status here - publishStatus( - protocolProvider, - PresenceStatus.AVAILABLE_THRESHOLD, - PresenceStatus.MAX_STATUS_VALUE); + if(!protocolProvider.isRegistered()) + { + saveStatusInformation(protocolProvider, itemName); + + GlobalDisplayDetailsActivator.getUIService() + .getLoginManager().login(protocolProvider); + } + else + // we search for highest available status here + publishStatus( + protocolProvider, + PresenceStatus.AVAILABLE_THRESHOLD, + PresenceStatus.MAX_STATUS_VALUE); } else if (itemName.equals(GlobalStatusEnum.DO_NOT_DISTURB_STATUS)) { - // status between online and away is DND - publishStatus( - protocolProvider, - PresenceStatus.ONLINE_THRESHOLD, - PresenceStatus.AWAY_THRESHOLD); + if(!protocolProvider.isRegistered()) + { + saveStatusInformation(protocolProvider, itemName); + + GlobalDisplayDetailsActivator.getUIService() + .getLoginManager().login(protocolProvider); + } + else + // status between online and away is DND + publishStatus( + protocolProvider, + PresenceStatus.ONLINE_THRESHOLD, + PresenceStatus.AWAY_THRESHOLD); } else if (itemName.equals(GlobalStatusEnum.AWAY_STATUS)) { - // a status in the away interval - publishStatus( - protocolProvider, - PresenceStatus.AWAY_THRESHOLD, - PresenceStatus.AVAILABLE_THRESHOLD); + if(!protocolProvider.isRegistered()) + { + saveStatusInformation(protocolProvider, itemName); + + GlobalDisplayDetailsActivator.getUIService() + .getLoginManager().login(protocolProvider); + } + else + // a status in the away interval + publishStatus( + protocolProvider, + PresenceStatus.AWAY_THRESHOLD, + PresenceStatus.AVAILABLE_THRESHOLD); } } } @@ -323,12 +392,35 @@ private void publishStatus( if (!protocolProvider.isRegistered()) return; + PresenceStatus status = getPresenceStatus( protocolProvider, + floorStatusValue, + ceilStatusValue); + + if (status != null) + { + OperationSetPresence presence + = protocolProvider + .getOperationSet(OperationSetPresence.class); + + new PublishPresenceStatusThread(protocolProvider, presence, status) + .start(); + + this.saveStatusInformation( protocolProvider, + status.getStatusName()); + } + } + + private PresenceStatus getPresenceStatus( + ProtocolProviderService protocolProvider, + int floorStatusValue, + int ceilStatusValue) + { OperationSetPresence presence = protocolProvider .getOperationSet(OperationSetPresence.class); if (presence == null) - return; + return null; Iterator statusSet = presence.getSupportedStatusSet(); @@ -357,14 +449,7 @@ private void publishStatus( } } - if (status != null) - { - new PublishPresenceStatusThread(protocolProvider, presence, status) - .start(); - - this.saveStatusInformation( protocolProvider, - status.getStatusName()); - } + return status; } /** @@ -380,7 +465,7 @@ private void saveStatusInformation( String statusName) { ConfigurationService configService - = GuiActivator.getConfigurationService(); + = GlobalDisplayDetailsActivator.getConfigurationService(); String prefix = "net.java.sip.communicator.impl.gui.accounts"; @@ -473,46 +558,55 @@ public void run() == OperationFailedException.GENERAL_ERROR) { String msgText = - GuiActivator.getResources().getI18NString( + GlobalDisplayDetailsActivator.getResources() + .getI18NString( "service.gui.STATUS_CHANGE_GENERAL_ERROR", new String[]{ protocolProvider.getAccountID().getUserID(), protocolProvider.getAccountID().getService()}); - new ErrorDialog(null, - GuiActivator.getResources().getI18NString( - "service.gui.GENERAL_ERROR"), msgText, e1) - .showDialog(); + GlobalDisplayDetailsActivator.getAlertUIService() + .showAlertDialog( + GlobalDisplayDetailsActivator.getResources() + .getI18NString("service.gui.GENERAL_ERROR"), + msgText, + e1); } else if (e1.getErrorCode() == OperationFailedException.NETWORK_FAILURE) { String msgText = - GuiActivator.getResources().getI18NString( + GlobalDisplayDetailsActivator.getResources() + .getI18NString( "service.gui.STATUS_CHANGE_NETWORK_FAILURE", new String[]{ protocolProvider.getAccountID().getUserID(), protocolProvider.getAccountID().getService()}); - new ErrorDialog(null, msgText, - GuiActivator.getResources().getI18NString( - "service.gui.NETWORK_FAILURE"), e1) - .showDialog(); + GlobalDisplayDetailsActivator.getAlertUIService() + .showAlertDialog( + msgText, + GlobalDisplayDetailsActivator.getResources() + .getI18NString("service.gui.NETWORK_FAILURE"), + e1); } else if (e1.getErrorCode() == OperationFailedException.PROVIDER_NOT_REGISTERED) { String msgText = - GuiActivator.getResources().getI18NString( + GlobalDisplayDetailsActivator.getResources() + .getI18NString( "service.gui.STATUS_CHANGE_NETWORK_FAILURE", new String[]{ protocolProvider.getAccountID().getUserID(), protocolProvider.getAccountID().getService()}); - new ErrorDialog(null, - GuiActivator.getResources().getI18NString( - "service.gui.NETWORK_FAILURE"), msgText, e1) - .showDialog(); + GlobalDisplayDetailsActivator.getAlertUIService() + .showAlertDialog( + GlobalDisplayDetailsActivator.getResources() + .getI18NString("service.gui.NETWORK_FAILURE"), + msgText, + e1); } logger.error("Error - changing status", e1); } diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf b/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf index 102ea9d26..91c101ec1 100644 --- a/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf +++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf @@ -10,7 +10,9 @@ Import-Package: org.jitsi.service.resources, org.osgi.framework, org.jitsi.util, net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.globalstatus, net.java.sip.communicator.service.protocol.event, + net.java.sip.communicator.service.gui, net.java.sip.communicator.util.account Export-Package: net.java.sip.communicator.service.globaldisplaydetails, net.java.sip.communicator.service.globaldisplaydetails.event diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java index 48b51e2d1..b0f578c88 100644 --- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java +++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java @@ -352,7 +352,7 @@ public ContactQuery queryContactSource(String query, int contactCount) { pattern = Pattern.compile(query); } - catch(PatternSyntaxException pse) + catch (PatternSyntaxException pse) { pattern = Pattern.compile( Pattern.quote(query)); diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java index 446d65a78..c8b7fb41d 100644 --- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java +++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java @@ -10,7 +10,6 @@ import net.java.sip.communicator.impl.gui.main.account.*; import net.java.sip.communicator.impl.gui.main.contactlist.*; -import net.java.sip.communicator.impl.gui.main.presence.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.callhistory.*; @@ -136,13 +135,6 @@ public void start(BundleContext bContext) try { - if (logger.isInfoEnabled()) - logger.info("GlobalStatus Service ...[REGISTERED]"); - - bundleContext.registerService(GlobalStatusService.class.getName(), - new GlobalStatusServiceImpl(), - null); - alertUIService = new AlertUIServiceImpl(); // Registers an implementation of the AlertUIService. bundleContext.registerService( AlertUIService.class.getName(), diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java index 8357af870..00842117d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java @@ -1302,7 +1302,7 @@ public void sendFile( final File file, final ChatTransport sendFileTransport = this.findFileTransferChatTransport(); - this.setSelectedChatTransport(sendFileTransport); + this.setSelectedChatTransport(sendFileTransport, true); if(file.length() > sendFileTransport.getMaximumFileLength()) { @@ -1968,10 +1968,20 @@ public void removeChatTransport(ChatTransport chatTransport) * Selects the given chat transport in the send via box. * * @param chatTransport the chat transport to be selected - */ - public void setSelectedChatTransport(ChatTransport chatTransport) - { - writeMessagePanel.setSelectedChatTransport(chatTransport); + * @param isMessageOrFileTransferReceived Boolean telling us if this change + * of the chat transport correspond to an effective switch to this new + * transform (a mesaage received from this transport, or a file transfer + * request received, or if the resource timeouted), or just a status update + * telling us a new chatTransport is now available (i.e. another device has + * startup). + */ + public void setSelectedChatTransport( + ChatTransport chatTransport, + boolean isMessageOrFileTransferReceived) + { + writeMessagePanel.setSelectedChatTransport( + chatTransport, + isMessageOrFileTransferReceived); } /** diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java index bf25ebce4..dd10a1fd7 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java @@ -69,8 +69,16 @@ public interface ChatSessionRenderer * Sets the given chatTransport to be the selected chat transport. * * @param chatTransport the ChatTransport to select + * @param isMessageOrFileTransferReceived Boolean telling us if this change + * of the chat transport correspond to an effective switch to this new + * transform (a mesaage received from this transport, or a file transfer + * request received, or if the resource timeouted), or just a status update + * telling us a new chatTransport is now available (i.e. another device has + * startup). */ - public void setSelectedChatTransport(ChatTransport chatTransport); + public void setSelectedChatTransport( + ChatTransport chatTransport, + boolean isMessageOrFileTransferReceived); /** * Updates the status of the given chat contact. diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java index 6b438884c..e527cac84 100755 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java @@ -89,6 +89,20 @@ public class ChatWritePanel private boolean smsMode = false; + /** + * A timer used to reset the transport resource to the bare ID if there was + * no activity from this resource since a buch a time. + */ + private java.util.Timer outdatedResourceTimer = null; + + /** + * Tells if the current resource is outdated. A timer has already been + * triggered, but when there is only a single resource there is no bare ID + * avaialble. Thus, flag this resource as outdated to switch to the bare ID + * when available. + */ + private boolean isOutdatedResource = true; + /** * Creates an instance of ChatWritePanel. * @@ -1008,9 +1022,17 @@ else if (transportSelectorBox != null) /** * Selects the given chat transport in the send via box. * - * @param chatTransport the chat transport to be selected + * @param chatTransport The chat transport to be selected. + * @param isMessageOrFileTransferReceived Boolean telling us if this change + * of the chat transport correspond to an effective switch to this new + * transform (a mesaage received from this transport, or a file transfer + * request received, or if the resource timeouted), or just a status update + * telling us a new chatTransport is now available (i.e. another device has + * startup). */ - public void setSelectedChatTransport(final ChatTransport chatTransport) + public void setSelectedChatTransport( + final ChatTransport chatTransport, + final boolean isMessageOrFileTransferReceived) { // We need to be sure that the following code is executed in the event // dispatch thread. @@ -1020,13 +1042,64 @@ public void setSelectedChatTransport(final ChatTransport chatTransport) { public void run() { - setSelectedChatTransport(chatTransport); + setSelectedChatTransport( + chatTransport, + isMessageOrFileTransferReceived); } }); return; } - if (transportSelectorBox != null) + // Check if this contact provider can manages several resources and thus + // provides a resource timeout via the basic IM operation set. + long timeout = -1; + OperationSetBasicInstantMessaging opSetBasicIM + = chatTransport.getProtocolProvider().getOperationSet( + OperationSetBasicInstantMessaging.class); + if(opSetBasicIM != null) + { + timeout = opSetBasicIM.getInactivityTimeout(); + } + + if(isMessageOrFileTransferReceived) + { + isOutdatedResource = false; + } + + // If this contact supports several resources, then schedule the timer: + // - If the resource is outdated, then trigger the timer now (to try to + // switch to the bare ID if now available). + // - If the new reousrce transport is really effective (i.e. we have + // received a message from this resource). + if(timeout != -1 + && (isMessageOrFileTransferReceived || isOutdatedResource)) + { + // If there was already a timeout, but the bare ID was not available + // (i.e. a single resource present). Then call the timeout procedure + // now in order to switch to the bare ID. + if(isOutdatedResource) + { + timeout = 0; + } + // Cancels the preceding timer. + if(outdatedResourceTimer != null) + { + outdatedResourceTimer.cancel(); + outdatedResourceTimer.purge(); + } + // Schedules the timer. + if(chatTransport.getResourceName() != null) + { + OutdatedResourceTimerTask task + = new OutdatedResourceTimerTask(); + outdatedResourceTimer = new java.util.Timer(); + outdatedResourceTimer.schedule(task, timeout); + } + } + + // Sets the new reousrce transport is really effective (i.e. we have + // received a message from this resource). + if(transportSelectorBox != null && isMessageOrFileTransferReceived) { transportSelectorBox.setSelected(chatTransport); } @@ -1374,4 +1447,44 @@ public void setEditorPaneBackground(Color color) this.centerPanel.setBackground(color); this.editorPane.setBackground(color); } + + + /** + * The task called when the current transport resource timed-out (no + * acitivty since a long time). Then this task resets the destination to the + * bare id. + */ + private class OutdatedResourceTimerTask + extends TimerTask + { + /** + * The action to be performed by this timer task. + */ + public void run() + { + outdatedResourceTimer = null; + + ChatTransport transport = null; + + Iterator transports + = chatPanel.getChatSession().getChatTransports(); + + while(transports.hasNext()) + { + transport = transports.next(); + + // We found the bare ID, then set it as the current resource + // transport. + if(transport.getResourceName() == null) + { + isOutdatedResource = false; + setSelectedChatTransport(transport, true); + return; + } + } + // If there is no bare ID avaialalbe, then set the current resource + // transport as outdated. + isOutdatedResource = true; + } + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java b/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java index 145e45127..f13ef3b1d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java @@ -698,14 +698,15 @@ private void addChatTransports( Contact contact, if (isSelectedContact) { currentChatTransport = chatTransport; - sessionRenderer.setSelectedChatTransport(chatTransport); + sessionRenderer.setSelectedChatTransport(chatTransport, false); } // If no current transport is set we choose the first one in the list. if (currentChatTransport == null) { currentChatTransport = chatTransports.get(0); - sessionRenderer.setSelectedChatTransport(currentChatTransport); + sessionRenderer + .setSelectedChatTransport(currentChatTransport, false); } if (contact.supportResources()) diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java index aaba89163..63ab88073 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java @@ -360,7 +360,7 @@ else if(eventType == MessageReceivedEvent.SMS_MESSAGE_RECEIVED) = chatPanel.getChatSession() .findChatTransportForDescriptor(protocolContact, resourceName); - chatPanel.setSelectedChatTransport(chatTransport); + chatPanel.setSelectedChatTransport(chatTransport, true); } /** @@ -614,7 +614,7 @@ public void fileTransferRequestReceived(FileTransferRequestEvent event) = chatPanel.getChatSession() .findChatTransportForDescriptor(sourceContact, null); - chatPanel.setSelectedChatTransport(chatTransport); + chatPanel.setSelectedChatTransport(chatTransport, true); // Opens the chat panel with the new message in the UI thread. chatWindowManager.openChat(chatPanel, false); diff --git a/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java b/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java index dd90821e4..48ec8e0b3 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java @@ -126,8 +126,7 @@ public int getType() */ public ContactQuery queryContactSource(String query) { - return queryContactSource( - Pattern.compile(query), LdapContactQuery.LDAP_MAX_RESULTS); + return queryContactSource(query, LdapContactQuery.LDAP_MAX_RESULTS); } /** @@ -139,7 +138,21 @@ public ContactQuery queryContactSource(String query) */ public ContactQuery queryContactSource(String query, int contactCount) { - return queryContactSource(Pattern.compile(query), contactCount); + Pattern pattern = null; + try + { + pattern = Pattern.compile(query); + } + catch (PatternSyntaxException pse) + { + pattern = Pattern.compile(Pattern.quote(query)); + } + + if(pattern != null) + { + return queryContactSource(pattern, contactCount); + } + return null; } /** diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java index 0005f5dca..00091b27c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java @@ -1079,4 +1079,14 @@ public void processPacket(Packet packet) jabberProvider.getConnection().sendPacket(mailboxQueryIQ); } } + + /** + * Returns the inactivity timeout in milliseconds. + * + * @return The inactivity timeout in milliseconds. Or -1 if undefined + */ + public long getInactivityTimeout() + { + return JID_INACTIVITY_TIMEOUT; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java index b1aa32b7e..89f662dcd 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java @@ -315,6 +315,13 @@ else if(calleeAddress.endsWith(GOOGLE_VOICE_DOMAIN)) if (fullCalleeURI == null) fullCalleeURI = discoverFullJid(calleeAddress, alwaysCallGtalk); + if (fullCalleeURI == null) + throw new OperationFailedException( + "Failed to create outgoing call to " + calleeAddress + + ". Could not find a resource which supports " + + "Jingle or Google Talk", + OperationFailedException.INTERNAL_ERROR); + DiscoverInfo di = null; try @@ -339,7 +346,7 @@ else if(calleeAddress.endsWith(GOOGLE_VOICE_DOMAIN)) { isGingle = false; } - else if (protocolProvider.isGTalkTesting() // test GTALK property + else if (protocolProvider.isGTalkTesting() // GTalk enabled locally // see if peer supports Google Talk voice && (hasGtalkCaps || alwaysCallGtalk)) { @@ -363,7 +370,7 @@ else if(di != null) fullCalleeURI + ": jingle and Google Talk not supported?"); throw new OperationFailedException( - "Failed to create OutgoingJingleSession.\n" + "Failed to create an outgoing call.\n" + fullCalleeURI + " does not support jingle or Google Talk", OperationFailedException.INTERNAL_ERROR); } @@ -440,8 +447,8 @@ else if (di != null) } /** - * Discover on which resource the remote user is connected and what are - * its priorities and capabilities. + * Discovers the resource for calleeAddress with the highest + * priority which supports either Jingle or Gtalk. Returns the full JID. * * @param calleeAddress the address of the callee * @param isAlwaysCallGtalk indicates if gtalk should be called @@ -515,7 +522,7 @@ else if(priority == bestPriority && jabberStatus != null) } } } - else if (protocolProvider.isGTalkTesting() // test GTALK property + else if (protocolProvider.isGTalkTesting() // GTalk enabled locally // see if peer supports Google Talk voice && (hasGtalkCaps || isAlwaysCallGtalk)) { diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java index 3b80d6254..61d120e23 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java @@ -10,6 +10,7 @@ import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.configuration.*; import org.jivesoftware.smack.util.*; import org.osgi.framework.*; @@ -214,6 +215,32 @@ public void modifyAccount( ProtocolProviderService protocolProvider, accountID.setAccountProperties(accountProperties); + // Remove additional STUN servers and Jingle Nodes properties. + // This is required because there is no check if some of them were + // removed during account edit process. Those that are valid will be + // restored during account storage process. + AccountManager accManager = getAccountManager(); + ConfigurationService configSrvc + = JabberActivator.getConfigurationService(); + String accountNodeName + = getAccountManager().getAccountNodeName(this, accountID); + String factoryPackage = accManager.getFactoryImplPackageName(this); + String accountPrefix = factoryPackage + "." + accountNodeName; + + List allProperties = configSrvc.getAllPropertyNames(); + String stunPrefix + = accountPrefix+"."+ProtocolProviderFactory.STUN_PREFIX; + String jinglePrefix + = accountPrefix+"."+JingleNodeDescriptor.JN_PREFIX; + for(String property : allProperties) + { + if( property.startsWith(stunPrefix) + || property.startsWith(jinglePrefix) ) + { + configSrvc.removeProperty(property); + } + } + // First store the account and only then load it as the load generates // an osgi event, the osgi event triggers (trhgough the UI) a call to // the register() method and it needs to acces the configuration service 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 5f47324ee..fb253b936 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -193,7 +193,7 @@ public class ProtocolProviderServiceJabberImpl "DESKTOP_STREAMING_DISABLED"; /** - * The name of the property under which the user may specify if the video + * The name of the property under which the user may specify if audio/video * calls should be disabled. */ private static final String IS_CALLING_DISABLED @@ -1313,7 +1313,19 @@ private void registerServiceDiscoveryManager() supportedFeatures.toArray( new String[supportedFeatures.size()])); - if(isGTalkTesting()) + boolean isCallingDisabled + = JabberActivator.getConfigurationService() + .getBoolean(IS_CALLING_DISABLED, false); + + boolean isCallingDisabledForAccount = false; + if (accountID != null && accountID.getAccountPropertyBoolean( + ProtocolProviderFactory.IS_CALLING_DISABLED_FOR_ACCOUNT, + false)) + isCallingDisabled = true; + + if(isGTalkTesting() + && !isCallingDisabled + && !isCallingDisabledForAccount) { // Add Google Talk "ext" capabilities discoveryManager.addExtFeature(CAPS_GTALK_WEB_VOICE); 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 d31feadda..86522b525 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -114,7 +114,7 @@ public class ProtocolProviderServiceSipImpl = "net.java.sip.communicator.impl.protocol.sip.DESKTOP_STREAMING_DISABLED"; /** - * The name of the property under which the user may specify if the video + * The name of the property under which the user may specify if audio/video * calls should be disabled. */ private static final String IS_CALLING_DISABLED diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java index e11a525ed..23d27f671 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java +++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java @@ -360,6 +360,12 @@ public class MsOutlookAddrBookContactQuery */ private int mapiMessageCount; + /** + * Boolea used to defined if we already get and logged a read contact + * property error. + */ + private boolean firstIMAPIPropGetPropFailureLogged = false; + /** * Initializes a new MsOutlookAddrBookContactQuery instance to * be performed by a specific @@ -812,11 +818,28 @@ private boolean onMailUser(String id) { logger.debug("Found contact id: " + id); } - Object[] props - = IMAPIProp_GetProps( - id, - MAPI_MAILUSER_PROP_IDS, - MAPI_UNICODE); + + Object[] props = null; + try + { + props + = IMAPIProp_GetProps(id, MAPI_MAILUSER_PROP_IDS, MAPI_UNICODE); + } + catch(MsOutlookMAPIHResultException ex) + { + if(ex.getHresultString().equals("MAPI_E_0x57") + && firstIMAPIPropGetPropFailureLogged == false) + { + firstIMAPIPropGetPropFailureLogged = true; + throw ex; + } + else if(!ex.getHresultString().equals("MAPI_E_0x57")) + { + throw ex; + } + return true; + } + long objType = 0; if(props != null && props[PR_OBJECT_TYPE] != null diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java index 411d46525..a54b7f7bd 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java +++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java @@ -99,4 +99,14 @@ private static String toString(long hResult) return s.toString(); } } + + /** + * Returns the string representation for the current hResult code. + * + * @return The string representation for the current hResult code. + */ + public String getHresultString() + { + return MsOutlookMAPIHResultException.toString(this.getHResult()); + } } diff --git a/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java b/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java index a90444835..99aa3eeaa 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java @@ -14,21 +14,108 @@ * dispatched through the system event queue. * * @author Yana Stamcheva + * @author Lyubomir Marinov */ public class LowPriorityEventQueue { /** - * Causes runnable to have its run - * method called in the event dispatch thread with low priority. + * Initializes a new Runnable which allows the repetitive execution + * the specific runnable on the application's EventQueue + * instance. * - * @param runnable the Runnable whose run - * method should be executed synchronously on the EventQueue + * @param runnable the Runnable which is to be repetitively + * executed on the application's EventQueue instance + * @return a new Runnable which allows the repetitive execution of + * the specified runnable on the application's EventQueue + * instance + */ + public static Runnable createRepetitiveInvokeLater(final Runnable runnable) + { + return + new Runnable() + { + /** + * The AWTEvent instance which is to execute the + * specified runnable on {@link #eventQueue} i.e. the + * application's EventQueue instance. + */ + private AWTEvent event; + + /** + * The EventQueue instance on which {@link #event} is + * to execute the specified runnable i.e. the + * application's EventQueue instance. + */ + private EventQueue eventQueue; + + /** + * The indicator which determines whether the execution of the + * specified runnable has already been scheduled and + * has not been performed yet. If true, invocations to + * {@link #run()} will do nothing. + */ + private boolean posted = false; + + /** + * Schedules the specified runnable to be executed + * (unless the execution has already been scheduled and has not + * been performed yet). + */ + public synchronized void run() + { + if (posted) + return; + + if (event == null) + { + Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); + + eventQueue = defaultToolkit.getSystemEventQueue(); + event + = new LowPriorityInvocationEvent( + defaultToolkit, + new Runnable() + { + public void run() + { + runInEvent(); + } + }); + } + + eventQueue.postEvent(event); + posted = true; + } + + /** + * Runs during the dispatch of {@link #event} and executed the + * specified runnable. + */ + private void runInEvent() + { + synchronized (this) + { + posted = false; + } + + runnable.run(); + } + }; + } + + /** + * Causes runnable to have its run method called in the + * event dispatch thread with low priority. + * + * @param runnable the Runnable whose run method should be + * executed synchronously on the EventQueue */ public static void invokeLater(Runnable runnable) { - Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent( - new LowPriorityInvocationEvent( - Toolkit.getDefaultToolkit(), runnable)); + Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); + + defaultToolkit.getSystemEventQueue().postEvent( + new LowPriorityInvocationEvent(defaultToolkit, runnable)); } /** @@ -38,7 +125,8 @@ public static void invokeLater(Runnable runnable) * priority as an update paint event, which is normally with lower priority * than other events. */ - private static class LowPriorityInvocationEvent extends InvocationEvent + private static class LowPriorityInvocationEvent + extends InvocationEvent { /** * Serial version UID. diff --git a/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java b/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java index 90b4aaacd..8bbdbe4f1 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java @@ -55,6 +55,20 @@ public class SoundLevelIndicator private static final String SOUND_LEVEL_INACTIVE_RIGHT = "service.gui.soundlevel.SOUND_LEVEL_INACTIVE_RIGHT"; + /** + * A runnable that will be used to update the sound level. + */ + private final LevelUpdate levelUpdate = new LevelUpdate(); + + /** + * The Runnable which schedules the execution of + * {@link #levelUpdate}. Introduced to better the garbage collection profile + * of the utilization of LowPriorityEventQueue. + * + * @see LowPriorityEventQueue#createRepetitiveInvokeLater(Runnable) + */ + private Runnable levelUpdateScheduler; + /** * The maximum possible sound level. */ @@ -116,11 +130,6 @@ public class SoundLevelIndicator */ private ImageIcon soundLevelInactiveImageRight; - /** - * A runnable that will be used to update the sound level. - */ - private LevelUpdate levelUpdate = new LevelUpdate(); - /** * Initializes a new SoundLevelIndicator instance. * @@ -138,6 +147,131 @@ public SoundLevelIndicator(int minSoundLevel, int maxSoundLevel) setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); } + /** + * Returns the number of sound level bars that we could currently show in + * this panel. + * + * @param width the current width of the call window + * @return the number of sound level bars that we could currently show in + * this panel + */ + private int getSoundBarCount(int width) + { + int soundBarWidth = soundLevelActiveImageLeft.getIconWidth(); + + return width / soundBarWidth; + } + + /** + * Reloads icons. + */ + public void loadSkin() + { + ResourceManagementService resources = DesktopUtilActivator.getResources(); + + soundLevelActiveImageLeft + = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT); + soundLevelActiveImageLeftGradient + = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT_GRADIENT); + soundLevelActiveImageMiddle + = resources.getImage(SOUND_LEVEL_ACTIVE_MIDDLE); + soundLevelActiveImageRight + = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT); + soundLevelActiveImageRightGradient + = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT); + + soundLevelInactiveImageLeft + = resources.getImage(SOUND_LEVEL_INACTIVE_LEFT); + soundLevelInactiveImageMiddle + = resources.getImage(SOUND_LEVEL_INACTIVE_MIDDLE); + soundLevelInactiveImageRight + = resources.getImage(SOUND_LEVEL_INACTIVE_RIGHT); + + if (!isPreferredSizeSet()) + { + int preferredHeight = 0; + int preferredWidth = 0; + + if (soundLevelActiveImageLeft != null) + { + int height = soundLevelActiveImageLeft.getIconHeight(); + int width = soundLevelActiveImageLeft.getIconWidth(); + + if (preferredHeight < height) + preferredHeight = height; + if (preferredWidth < width) + preferredWidth = width; + } + if (soundLevelInactiveImageLeft != null) + { + int height = soundLevelInactiveImageLeft.getIconHeight(); + int width = soundLevelInactiveImageLeft.getIconWidth(); + + if (preferredHeight < height) + preferredHeight = height; + if (preferredWidth < width) + preferredWidth = width; + } + if ((preferredHeight > 0) && (preferredWidth > 0)) + setPreferredSize( + new Dimension( + 10 * preferredWidth, + preferredHeight)); + } + + updateSoundLevel(soundLevel); + } + + public void resetSoundLevel() + { + soundLevel = minSoundLevel; + updateSoundLevel(minSoundLevel); + } + + @Override + public void setBounds(int x, int y, int width, int height) + { + super.setBounds(x, y, width, height); + + int newSoundBarCount = getSoundBarCount(getWidth()); + + if (newSoundBarCount > 0) + { + while (newSoundBarCount < soundBarCount) + { + for (int i = getComponentCount() - 1; i >= 0; i--) + { + Component c = getComponent(i); + + if (c instanceof JLabel) + { + remove(c); + soundBarCount--; + break; + } + } + } + while (soundBarCount < newSoundBarCount) + { + JLabel soundBar; + if (soundBarCount == 0) + soundBar = new JLabel(soundLevelInactiveImageLeft); + else if (soundBarCount == newSoundBarCount - 1) + soundBar = new JLabel(soundLevelInactiveImageRight); + else + soundBar = new JLabel(soundLevelInactiveImageMiddle); + + soundBar.setVerticalAlignment(JLabel.CENTER); + add(soundBar); + soundBarCount++; + } + } + + updateSoundLevel(soundLevel); + revalidate(); + repaint(); + } + /** * Update the sound level indicator component to fit the given values. * @@ -146,7 +280,21 @@ public SoundLevelIndicator(int minSoundLevel, int maxSoundLevel) public void updateSoundLevel(int soundLevel) { levelUpdate.setSoundLevel(soundLevel); - LowPriorityEventQueue.invokeLater(levelUpdate); + + Runnable levelUpdateScheduler; + + synchronized (this) + { + if (this.levelUpdateScheduler == null) + { + this.levelUpdateScheduler + = LowPriorityEventQueue.createRepetitiveInvokeLater( + levelUpdate); + } + levelUpdateScheduler = this.levelUpdateScheduler; + } + + levelUpdateScheduler.run(); } /** @@ -243,132 +391,7 @@ else if (i == components.length - 1) } repaint(); - } - - public void resetSoundLevel() - { - soundLevel = minSoundLevel; - updateSoundLevel(minSoundLevel); - } - - @Override - public void setBounds(int x, int y, int width, int height) - { - super.setBounds(x, y, width, height); - - int newSoundBarCount = getSoundBarCount(getWidth()); - - if (newSoundBarCount > 0) - { - while (newSoundBarCount < soundBarCount) - { - for (int i = getComponentCount() - 1; i >= 0; i--) - { - Component c = getComponent(i); - - if (c instanceof JLabel) - { - remove(c); - soundBarCount--; - break; - } - } - } - while (soundBarCount < newSoundBarCount) - { - JLabel soundBar; - if (soundBarCount == 0) - soundBar = new JLabel(soundLevelInactiveImageLeft); - else if (soundBarCount == newSoundBarCount - 1) - soundBar = new JLabel(soundLevelInactiveImageRight); - else - soundBar = new JLabel(soundLevelInactiveImageMiddle); - - soundBar.setVerticalAlignment(JLabel.CENTER); - add(soundBar); - soundBarCount++; - } - } - - updateSoundLevel(soundLevel); - revalidate(); - repaint(); - } - - /** - * Returns the number of sound level bars that we could currently show in - * this panel. - * - * @param width the current width of the call window - * @return the number of sound level bars that we could currently show in - * this panel - */ - private int getSoundBarCount(int width) - { - int soundBarWidth = soundLevelActiveImageLeft.getIconWidth(); - - return width / soundBarWidth; - } - - /** - * Reloads icons. - */ - public void loadSkin() - { - ResourceManagementService resources = DesktopUtilActivator.getResources(); - - soundLevelActiveImageLeft - = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT); - soundLevelActiveImageLeftGradient - = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT_GRADIENT); - soundLevelActiveImageMiddle - = resources.getImage(SOUND_LEVEL_ACTIVE_MIDDLE); - soundLevelActiveImageRight - = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT); - soundLevelActiveImageRightGradient - = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT); - - soundLevelInactiveImageLeft - = resources.getImage(SOUND_LEVEL_INACTIVE_LEFT); - soundLevelInactiveImageMiddle - = resources.getImage(SOUND_LEVEL_INACTIVE_MIDDLE); - soundLevelInactiveImageRight - = resources.getImage(SOUND_LEVEL_INACTIVE_RIGHT); - - if (!isPreferredSizeSet()) - { - int preferredHeight = 0; - int preferredWidth = 0; - - if (soundLevelActiveImageLeft != null) - { - int height = soundLevelActiveImageLeft.getIconHeight(); - int width = soundLevelActiveImageLeft.getIconWidth(); - - if (preferredHeight < height) - preferredHeight = height; - if (preferredWidth < width) - preferredWidth = width; - } - if (soundLevelInactiveImageLeft != null) - { - int height = soundLevelInactiveImageLeft.getIconHeight(); - int width = soundLevelInactiveImageLeft.getIconWidth(); - - if (preferredHeight < height) - preferredHeight = height; - if (preferredWidth < width) - preferredWidth = width; - } - if ((preferredHeight > 0) && (preferredWidth > 0)) - setPreferredSize( - new Dimension( - 10 * preferredWidth, - preferredHeight)); - } - - updateSoundLevel(soundLevel); - } + }; /** * Runnable used to update sound levels. @@ -397,5 +420,5 @@ public void setSoundLevel(int soundLevel) { this.soundLevel = soundLevel; } - }; + } } diff --git a/src/net/java/sip/communicator/service/gui/UIService.java b/src/net/java/sip/communicator/service/gui/UIService.java index 9ad472c51..68ab90734 100644 --- a/src/net/java/sip/communicator/service/gui/UIService.java +++ b/src/net/java/sip/communicator/service/gui/UIService.java @@ -14,6 +14,7 @@ import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.account.*; /** * The UIService offers generic access to the graphical user interface @@ -465,4 +466,11 @@ public ContactList createContactListComponent( * @return a collection of all currently in progress calls. */ public Collection getInProgressCalls(); + + /** + * Returns the login manager used by the current UI implementation. + * + * @return the login manager used by the current UI implementation + */ + public LoginManager getLoginManager(); } diff --git a/src/net/java/sip/communicator/service/gui/gui.manifest.mf b/src/net/java/sip/communicator/service/gui/gui.manifest.mf index 7778af2a2..5bbfcbcce 100644 --- a/src/net/java/sip/communicator/service/gui/gui.manifest.mf +++ b/src/net/java/sip/communicator/service/gui/gui.manifest.mf @@ -8,6 +8,7 @@ Import-Package: org.osgi.framework, org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, + net.java.sip.communicator.util.account, net.java.sip.communicator.service.contactsource, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.protocol diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java index effade7f5..74077c6f5 100644 --- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java +++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java @@ -367,4 +367,14 @@ public void sendInstantMessage( Contact to, { sendInstantMessage(to, message); } + + /** + * Returns the inactivity timeout in milliseconds. + * + * @return The inactivity timeout in milliseconds. Or -1 if undefined + */ + public long getInactivityTimeout() + { + return -1; + } } diff --git a/src/net/java/sip/communicator/service/protocol/AccountManager.java b/src/net/java/sip/communicator/service/protocol/AccountManager.java index e6e76ee4b..02c044ac5 100644 --- a/src/net/java/sip/communicator/service/protocol/AccountManager.java +++ b/src/net/java/sip/communicator/service/protocol/AccountManager.java @@ -247,7 +247,7 @@ private void fireStoredAccountsLoaded(ProtocolProviderFactory factory) * @param factory the factory which package will be returned. * @return the package name of the factory. */ - private String getFactoryImplPackageName(ProtocolProviderFactory factory) + public String getFactoryImplPackageName(ProtocolProviderFactory factory) { String className = factory.getClass().getName(); @@ -660,30 +660,7 @@ public void storeAccount( = ProtocolProviderActivator.getConfigurationService(); String factoryPackage = getFactoryImplPackageName(factory); - // First check if such accountID already exists in the configuration. - List storedAccounts = - configurationService.getPropertyNamesByPrefix(factoryPackage, true); - String accountUID = accountID.getAccountUniqueID(); - String accountNodeName = null; - - for (Iterator storedAccountIter = storedAccounts.iterator(); - storedAccountIter.hasNext();) - { - String storedAccount = storedAccountIter.next(); - - // If the property is not related to an account we skip it. - int dotIndex = storedAccount.lastIndexOf("."); - if (!storedAccount.substring(dotIndex + 1) - .startsWith(ACCOUNT_UID_PREFIX)) - continue; - - String storedAccountUID = - configurationService.getString(storedAccount + "." - + ProtocolProviderFactory.ACCOUNT_UID); - - if (storedAccountUID.equals(accountUID)) - accountNodeName = configurationService.getString(storedAccount); - } + String accountNodeName = getAccountNodeName(factory, accountID); Map configurationProperties = new HashMap(); @@ -782,6 +759,49 @@ else if(property.endsWith("." + ProtocolProviderFactory.PASSWORD)) + " for package " + factoryPackage); } + /** + * Gets account node name under which account configuration properties are + * stored. + * + * @param factory account's protocol provider factory + * @param accountID account for which the prefix will be returned + * @return configuration prefix for given accountID if exists or + * null otherwise + */ + public String getAccountNodeName( ProtocolProviderFactory factory, + AccountID accountID ) + { + ConfigurationService configurationService + = ProtocolProviderActivator.getConfigurationService(); + String factoryPackage = getFactoryImplPackageName(factory); + + // First check if such accountID already exists in the configuration. + List storedAccounts = + configurationService.getPropertyNamesByPrefix(factoryPackage, true); + String accountUID = accountID.getAccountUniqueID(); + String accountNodeName = null; + + for (Iterator storedAccountIter = storedAccounts.iterator(); + storedAccountIter.hasNext();) + { + String storedAccount = storedAccountIter.next(); + + // If the property is not related to an account we skip it. + int dotIndex = storedAccount.lastIndexOf("."); + if (!storedAccount.substring(dotIndex + 1) + .startsWith(ACCOUNT_UID_PREFIX)) + continue; + + String storedAccountUID + = configurationService.getString( + storedAccount + "." + ProtocolProviderFactory.ACCOUNT_UID); + + if (storedAccountUID.equals(accountUID)) + accountNodeName = configurationService.getString(storedAccount); + } + return accountNodeName; + } + /** * Removes the account with accountID from the set of accounts * that are persistently stored inside the configuration service. diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java index e76c259a6..763639445 100644 --- a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java +++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java @@ -138,4 +138,11 @@ public void sendInstantMessage( Contact to, * false otherwise. */ public boolean isContentTypeSupported(String contentType, Contact contact); + + /** + * Returns the inactivity timeout in milliseconds. + * + * @return The inactivity timeout in milliseconds. Or -1 if undefined + */ + public long getInactivityTimeout(); } diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java index 7b3f5e38a..812d884eb 100644 --- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java +++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java @@ -1196,7 +1196,7 @@ protected void stop(ServiceRegistration registeredAccount) * * @return AccountManager of the protocol */ - private AccountManager getAccountManager() + protected AccountManager getAccountManager() { BundleContext bundleContext = getBundleContext(); ServiceReference serviceReference = diff --git a/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java b/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java index 95650df10..ac039aeab 100644 --- a/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java +++ b/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java @@ -34,12 +34,12 @@ public class GlobalStatusEnum /** * Indicates that the user is connected and eager to communicate. */ - public static final String FREE_FOR_CHAT_STATUS = "FreeForChat"; + public static final String FREE_FOR_CHAT_STATUS = "Free For Chat"; /** * Indicates that the user is connected and eager to communicate. */ - public static final String DO_NOT_DISTURB_STATUS = "DoNotDisturb"; + public static final String DO_NOT_DISTURB_STATUS = "Do Not Disturb"; /** * The Online status. Indicate that the user is able and willing to diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java index 948afc021..37be06b43 100644 --- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java +++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java @@ -506,7 +506,7 @@ protected MediaDirection getRemoteDirection( } else remoteDirection = null; - return null; + return remoteDirection; } /**