diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java index a4a6eac4e..3de8356ac 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java @@ -667,7 +667,13 @@ private void doUpdateSettingsPanelInEventDispatchThread( settingsPanel.remove(remoteLevel); } - chatButton.setVisible(getIMCapableCallPeers(1).size() == 1); + /* + * We do not support chat conferencing with the participants in a + * telephony conference at this time so we do not want the chatButton + * visible in such a scenario. + */ + chatButton.setVisible( + !isConference && (getIMCapableCallPeers(1).size() == 1)); /* * TODO The full-screen support is currently broken so the * fullScreenButton is not enabled or shown. @@ -677,6 +683,12 @@ private void doUpdateSettingsPanelInEventDispatchThread( updateMergeButtonState(); List calls = callConference.getCalls(); + /* + * OperationSetAdvancedTelephony implements call transfer. The feature + * is not supported if the local user/peer is a conference focus. + * Instead of disabling the transferCallButton in this case though, we + * want it hidden. + */ boolean advancedTelephony = !calls.isEmpty(); boolean telephonyConferencing = false; boolean videoTelephony = false; @@ -737,6 +749,7 @@ private void doUpdateSettingsPanelInEventDispatchThread( conferenceButton.setEnabled(telephonyConferencing); transferCallButton.setEnabled(advancedTelephony); + transferCallButton.setVisible(!callConference.isConferenceFocus()); /* * The videoButton is a beast of its own kind because it depends not @@ -1949,7 +1962,6 @@ private void updateSettingsPanelInEventDispatchThread( * method updateViewFromModelInEventDispatchThread we have made it easy * to add code before and/or after the invocation of the delegate. */ - doUpdateSettingsPanelInEventDispatchThread(callConferenceIsEnded); } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java index 2f4c2c110..99b5f57d3 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java @@ -591,46 +591,48 @@ protected ConferenceCallPeerRenderer updateViewFromModel( { /* * The local peer/user will be represented by a Call which has a - * CallPeer which provides local video. + * CallPeer who provides local video. However, if the user has + * selected to hide the local video, the local peer/user will not be + * represented at all. */ Component video = null; - for (Call aCall : callConference.getCalls()) + if (uiVideoHandler.isLocalVideoVisible()) { - Iterator callPeerIter - = aCall.getCallPeers(); - OperationSetVideoTelephony videoTelephony - = aCall.getProtocolProvider().getOperationSet( - OperationSetVideoTelephony.class); - boolean localVideoIsVisible - = (videoTelephony != null) - && uiVideoHandler.isLocalVideoVisible(); - - while (callPeerIter.hasNext()) + for (Call aCall : callConference.getCalls()) { - callPeer = callPeerIter.next(); + Iterator callPeerIter + = aCall.getCallPeers(); + OperationSetVideoTelephony videoTelephony + = aCall.getProtocolProvider().getOperationSet( + OperationSetVideoTelephony.class); - if (localVideoIsVisible) + while (callPeerIter.hasNext()) { - try - { - video - = videoTelephony.getLocalVisualComponent( - callPeer); - } - catch (OperationFailedException ofe) + callPeer = callPeerIter.next(); + + if (videoTelephony != null) { - logger.error( - "Failed to retrieve the local video" - + " for display", - ofe); + try + { + video + = videoTelephony.getLocalVisualComponent( + callPeer); + } + catch (OperationFailedException ofe) + { + logger.error( + "Failed to retrieve the local video" + + " for display", + ofe); + } + if (video != null) + break; } - if (video != null) - break; } + if (video != null) + break; } - if (video != null) - break; } if (callPeer == null) 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 755d07364..6c9442fd0 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java @@ -431,13 +431,20 @@ else if(di != null) { logger.info("initiate Gingle call"); CallGTalkImpl callGTalk = new CallGTalkImpl(this); + CallConference conference = call.getConference(); MediaUseCase useCase = call.getMediaUseCase(); - boolean isVideo = call.isLocalVideoAllowed(useCase); + boolean video = call.isLocalVideoAllowed(useCase); - CallConference callConference = call.getConference(); - callConference.removeCall(call); - callGTalk.setConference(callConference); - callGTalk.setLocalVideoAllowed(isVideo, useCase); + /* + * The specified call is being replaced by callGTalk as its + * runtime representation. Make sure that they do not exist as + * two separate Call instances= Otherwise, they would, for + * example, appear to be in a telephony conference. + */ + call.setConference(null); + callGTalk.setConference(conference); + + callGTalk.setLocalVideoAllowed(video, useCase); peer = callGTalk.initiateGTalkSession( fullCalleeURI, diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java index 3931c14f4..ce0922f97 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java @@ -49,15 +49,15 @@ public class OperationSetTelephonyConferencingJabberImpl = Logger.getLogger(OperationSetTelephonyConferencingJabberImpl.class); /** - * The value of the version attribute to be specified in the - * outgoing conference-info root XML elements. + * Synchronization object. */ - private int version = 1; + private final Object lock = new Object(); /** - * Synchronization object. + * The value of the version attribute to be specified in the + * outgoing conference-info root XML elements. */ - private final Object objSync = new Object(); + private int version = 1; /** * Initializes a new OperationSetTelephonyConferencingJabberImpl @@ -88,13 +88,14 @@ protected void notifyCallPeers(Call call) { if (call.isConferenceFocus()) { - synchronized (objSync) + synchronized (lock) { - // send conference-info to all CallPeers of the call. - Iterator callPeerIter = call.getCallPeers(); - - while (callPeerIter.hasNext()) - notify(callPeerIter.next()); + // send conference-info to all CallPeers of the specified call. + for (Iterator i = call.getCallPeers(); + i.hasNext();) + { + notify(i.next()); + } version++; } @@ -133,7 +134,7 @@ private void notify(CallPeer callPeer) logger.warn("Failed to retrieve DiscoverInfo for " + to, xmppe); } - IQ iq = getConferenceInfo((CallPeerJabberImpl)callPeer, version); + IQ iq = getConferenceInfo((CallPeerJabberImpl) callPeer, version); if (iq != null) parentProvider.getConnection().sendPacket(iq); diff --git a/src/net/java/sip/communicator/service/protocol/CallConference.java b/src/net/java/sip/communicator/service/protocol/CallConference.java index f1c93ea7f..23674cc9f 100644 --- a/src/net/java/sip/communicator/service/protocol/CallConference.java +++ b/src/net/java/sip/communicator/service/protocol/CallConference.java @@ -795,7 +795,7 @@ private void onCallPeerEvent(CallPeerEvent ev) * telephony conference changed as a result of the method call; otherwise, * false */ - public boolean removeCall(Call call) + boolean removeCall(Call call) { if (call == null) return false; 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 9d6812cac..948afc021 100644 --- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java +++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java @@ -268,9 +268,9 @@ public void callPeerAdded(CallPeerEvent event) * @param event a CallPeerEvent which specifies the * CallPeer which has been removed from a Call */ - @SuppressWarnings("unchecked") public void callPeerRemoved(CallPeerEvent event) { + @SuppressWarnings("unchecked") MediaAwareCallPeerT callPeer = (MediaAwareCallPeerT) event.getSourceCallPeer(); @@ -467,17 +467,15 @@ else if (MediaType.VIDEO.toString().equalsIgnoreCase(type)) */ private String getEndpointStatus(Node endpoint) { - NodeList endpointChildList = endpoint.getChildNodes(); - int endpoingChildCount = endpointChildList.getLength(); + NodeList childNodes = endpoint.getChildNodes(); + int childCount = childNodes.getLength(); - for (int endpointChildIndex = 0; - endpointChildIndex < endpoingChildCount; - endpointChildIndex++) + for (int i = 0; i < childCount; i++) { - Node endpointChild = endpointChildList.item(endpointChildIndex); + Node child = childNodes.item(i); - if (ELEMENT_STATUS.equals(endpointChild.getNodeName())) - return endpointChild.getTextContent(); + if (ELEMENT_STATUS.equals(child.getNodeName())) + return child.getTextContent(); } return null; } @@ -686,24 +684,19 @@ protected abstract CalleeAddressT parseAddressString( * old and new values of the property * @see PropertyChangeListener#propertyChange(PropertyChangeEvent) */ - @SuppressWarnings("unchecked") public void propertyChange(PropertyChangeEvent ev) { String propertyName = ev.getPropertyName(); - if (CallPeerMediaHandler.AUDIO_LOCAL_SSRC.equals( - propertyName) - || CallPeerMediaHandler.AUDIO_REMOTE_SSRC.equals( - propertyName) - || CallPeerMediaHandler.VIDEO_LOCAL_SSRC.equals( - propertyName) - || CallPeerMediaHandler.VIDEO_REMOTE_SSRC.equals( - propertyName)) + if (CallPeerMediaHandler.AUDIO_LOCAL_SSRC.equals(propertyName) + || CallPeerMediaHandler.AUDIO_REMOTE_SSRC.equals(propertyName) + || CallPeerMediaHandler.VIDEO_LOCAL_SSRC.equals(propertyName) + || CallPeerMediaHandler.VIDEO_REMOTE_SSRC.equals(propertyName)) { - Call call - = ((CallPeerMediaHandler) ev.getSource()) - .getPeer() - .getCall(); + @SuppressWarnings("unchecked") + CallPeerMediaHandler mediaHandler + = (CallPeerMediaHandler) ev.getSource(); + Call call = mediaHandler.getPeer().getCall(); if (call != null) notifyAll(call); @@ -798,23 +791,23 @@ private void setConferenceInfoDocument( continue; /* - * Determine the ConferenceMembers which are no longer in the - * list. + * Determine the ConferenceMembers who are no longer in the list + * i.e. are to be removed. */ - AbstractConferenceMember existingConferenceMember = null; + AbstractConferenceMember conferenceMember = null; for (int i = 0; i < toRemoveCount; i++) { - ConferenceMember conferenceMember + ConferenceMember aConferenceMember = toRemove[i]; - if ((conferenceMember != null) + if ((aConferenceMember != null) && address.equalsIgnoreCase( - conferenceMember.getAddress())) + aConferenceMember.getAddress())) { toRemove[i] = null; - existingConferenceMember - = (AbstractConferenceMember) conferenceMember; + conferenceMember + = (AbstractConferenceMember) aConferenceMember; break; } } @@ -822,9 +815,9 @@ private void setConferenceInfoDocument( // Create the new ones. boolean addConferenceMember; - if (existingConferenceMember == null) + if (conferenceMember == null) { - existingConferenceMember + conferenceMember = new AbstractConferenceMember(callPeer, address); addConferenceMember = true; } @@ -832,7 +825,7 @@ private void setConferenceInfoDocument( addConferenceMember = false; // Update the existing ones. - if (existingConferenceMember != null) + if (conferenceMember != null) { NodeList userChildList = user.getChildNodes(); int userChildCount = userChildList.getLength(); @@ -868,15 +861,15 @@ else if (ELEMENT_ENDPOINT.equals(userChildName)) conferenceMemberProperties); } } - existingConferenceMember.setDisplayName(displayName); - existingConferenceMember.setEndpointStatus(endpointStatus); + conferenceMember.setDisplayName(displayName); + conferenceMember.setEndpointStatus(endpointStatus); changed - = existingConferenceMember.setProperties( + = conferenceMember.setProperties( conferenceMemberProperties); if (addConferenceMember) - callPeer.addConferenceMember(existingConferenceMember); + callPeer.addConferenceMember(conferenceMember); } } } diff --git a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java index c8b959777..04d955658 100644 --- a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java @@ -195,6 +195,10 @@ public boolean requestKeyFrame() /** * The PropertyChangeListener which listens to changes in the * values of the properties of the MediaStreams of this instance. + * Since CallPeerMediaHandler wraps around/shares a + * MediaHandler, streamPropertyChangeListener actually + * listens to PropertyChangeEvents fired by the + * MediaHandler in question and forwards them as its own. */ private final PropertyChangeListener streamPropertyChangeListener = new PropertyChangeListener() diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java index fad955ded..081740dc0 100644 --- a/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java @@ -1212,9 +1212,8 @@ private void setAudioStream(AudioMediaStream audioStream) this.audioStream.setStreamAudioLevelListener(null); } - this.audioStream - .removePropertyChangeListener( - streamPropertyChangeListener); + this.audioStream.removePropertyChangeListener( + streamPropertyChangeListener); this.audioStream.close(); } @@ -1225,9 +1224,8 @@ private void setAudioStream(AudioMediaStream audioStream) if (this.audioStream != null) { - this.audioStream - .addPropertyChangeListener( - streamPropertyChangeListener); + this.audioStream.addPropertyChangeListener( + streamPropertyChangeListener); audioLocalSSRC = this.audioStream.getLocalSourceID(); audioRemoteSSRC = this.audioStream.getRemoteSourceID();