- Fixes a race condition in the Jitsi VideoBridge/colibri support which could lead to failure to associate videos with the telephony conference participants who are sending them.

- Fixes a NullPointerException in one-to-one calls caused by the support for remote desktop control.
cusax-fix
Lyubomir Marinov 14 years ago
parent c5db7000df
commit a6e1daf78e

@ -13,85 +13,55 @@
import java.awt.event.*;
/**
* This class listens to mouse and keyboard event for dekstop sharing at the
* This class listens to mouse and keyboard event for desktop sharing at the
* client side, in order to send moves, clicks and key strokes to the server.
*
* @author Vincent Lucas
*/
public class DesktopSharingMouseAndKeyboardListener
implements RemoteControlListener,
KeyListener,
MouseListener,
MouseMotionListener
KeyListener,
MouseListener,
MouseMotionListener
{
/**
* The remote controlled call peer to which the events must be sent.
*/
private CallPeer remoteCallPeer;
private final CallPeer callPeer;
/**
* The video component displqying the remote desktop.
* The operation set which received the granted/revoked desktop sharing
* rights and to which, we are sending the mouse and key events.
*/
private Component videoComponent = null;
private final OperationSetDesktopSharingClient opSetDesktopSharingClient;
/**
* An object get mutual exclusion access to the videoComponent.
* The video component displaying the remote desktop.
*/
private Object videoComponentMutex = new Object();
private Component videoComponent = null;
/**
* The oeration set which received the granted/revoked desktop sharing
* rights and to which, we are sending the mouse and key events.
* An object get mutual exclusion access to the videoComponent.
*/
private OperationSetDesktopSharingClient opSetDesktopSharingClient = null;
private final Object videoComponentMutex = new Object();
/**
* Creates a new listener of mouse and key event for a the
* video diplaying the streamed remote desktop. The video component is null
* video displaying the streamed remote desktop. The video component is null
* until calling the setVideoComponent function.
*
* @param remoteCallPeer The remote controlled call peer to which the events
* @param callPeer The remote controlled call peer to which the events
* must be sent.
*/
public DesktopSharingMouseAndKeyboardListener(CallPeer remoteCallPeer)
public DesktopSharingMouseAndKeyboardListener(CallPeer callPeer)
{
this.remoteCallPeer = remoteCallPeer;
this.callPeer = callPeer;
this.opSetDesktopSharingClient
= remoteCallPeer.getProtocolProvider().getOperationSet(
opSetDesktopSharingClient
= callPeer.getProtocolProvider().getOperationSet(
OperationSetDesktopSharingClient.class);
}
/**
* Sets the video diplaying component for the streamed remote desktop.
*
* @param videoComponenet The video component displqying the remote desktop.
*/
public void setVideoComponent(Component videoComponent)
{
synchronized(this.videoComponentMutex)
{
// If there was an old video component, and no new one, then
// unregisters to the operation set.
if(this.videoComponent != null
&& videoComponent == null)
{
// The remove remote control listener will also be called
// directly by the operationst when the peer state change.
opSetDesktopSharingClient.removeRemoteControlListener(this);
}
// If there was no video component, and a new one is set, then
// registers to the operation set.
else if(this.videoComponent == null
&& videoComponent != null)
{
opSetDesktopSharingClient.addRemoteControlListener(this);
}
this.videoComponent = videoComponent;
}
}
/**
* Returns the remote-controlled CallPeer.
*
@ -99,90 +69,66 @@ else if(this.videoComponent == null
*/
public CallPeer getCallPeer()
{
return this.remoteCallPeer;
return callPeer;
}
/**
* This method is called when remote control has been granted.
* Invoked when a key has been pressed.
*
* @param event The event which grants us the control of the remote call
* peer.
* @param e The keyboard event.
*/
public void remoteControlGranted(RemoteControlGrantedEvent event)
public void keyPressed(KeyEvent e)
{
synchronized(this.videoComponentMutex)
{
if(this.videoComponent != null)
{
this.videoComponent.addKeyListener(this);
this.videoComponent.addMouseListener(this);
this.videoComponent.addMouseMotionListener(this);
}
}
}
/**
* This method is called when remote control has been revoked.
* Invoked when a key has been released.
*
* @param event The event which revokes us the control of the remote call
* peer.
* @param e The keyboard event.
*/
public void remoteControlRevoked(RemoteControlRevokedEvent event)
public void keyReleased(KeyEvent e)
{
synchronized(this.videoComponentMutex)
{
if(this.videoComponent != null)
{
this.videoComponent.removeKeyListener(this);
this.videoComponent.removeMouseListener(this);
this.videoComponent.removeMouseMotionListener(this);
}
}
}
/**
* Invoked when a mouse button is pressed on a
* component and then dragged.
* Invoked when a key has been typed.
*
* @param e The mouse dragged event.
* @param e The keyboard event.
*/
public void mouseDragged(MouseEvent e)
public void keyTyped(KeyEvent e)
{
opSetDesktopSharingClient.sendMouseEvent(
remoteCallPeer,
e,
videoComponent.getBounds().getSize());
opSetDesktopSharingClient.sendKeyboardEvent(callPeer, e);
}
/**
* Invoked when the mouse cursor has been moved
* onto a component but no buttons have been pushed.
* Invoked when the mouse button has been clicked (pressed and released) on
* a component.
*
* @param e The mouse moved event.
* @param e The mouse event.
*/
public void mouseMoved(MouseEvent e)
public void mouseClicked(MouseEvent e)
{
opSetDesktopSharingClient.sendMouseEvent(
remoteCallPeer,
callPeer,
e,
videoComponent.getBounds().getSize());
videoComponent.getSize());
}
/**
* Invoked when the mouse button has been clicked (pressed and released) on
* a component.
* Invoked when a mouse button is pressed on a
* component and then dragged.
*
* @param e The mouse event.
* @param e The mouse dragged event.
*/
public void mouseClicked(MouseEvent e)
public void mouseDragged(MouseEvent e)
{
opSetDesktopSharingClient.sendMouseEvent(
remoteCallPeer,
callPeer,
e,
videoComponent.getBounds().getSize());
videoComponent.getSize());
}
/**
* Invoked when the mouse enters a component.
*
@ -201,6 +147,20 @@ public void mouseExited(MouseEvent e)
{
}
/**
* Invoked when the mouse cursor has been moved
* onto a component but no buttons have been pushed.
*
* @param e The mouse moved event.
*/
public void mouseMoved(MouseEvent e)
{
opSetDesktopSharingClient.sendMouseEvent(
callPeer,
e,
videoComponent.getSize());
}
/**
* Invoked when a mouse button has been pressed on a component.
*
@ -209,9 +169,9 @@ public void mouseExited(MouseEvent e)
public void mousePressed(MouseEvent e)
{
opSetDesktopSharingClient.sendMouseEvent(
remoteCallPeer,
callPeer,
e,
videoComponent.getBounds().getSize());
videoComponent.getSize());
}
/**
@ -222,38 +182,78 @@ public void mousePressed(MouseEvent e)
public void mouseReleased(MouseEvent e)
{
opSetDesktopSharingClient.sendMouseEvent(
remoteCallPeer,
callPeer,
e,
videoComponent.getBounds().getSize());
videoComponent.getSize());
}
/**
* Invoked when a key has been pressed.
* This method is called when remote control has been granted.
*
* @param e The keyborad event.
* @param event The event which grants us the control of the remote call
* peer.
*/
public void keyPressed(KeyEvent e)
public void remoteControlGranted(RemoteControlGrantedEvent event)
{
synchronized(videoComponentMutex)
{
if(videoComponent != null)
{
videoComponent.addKeyListener(this);
videoComponent.addMouseListener(this);
videoComponent.addMouseMotionListener(this);
}
}
}
/**
* Invoked when a key has been released.
* This method is called when remote control has been revoked.
*
* @param e The keyborad event.
* @param event The event which revokes us the control of the remote call
* peer.
*/
public void keyReleased(KeyEvent e)
public void remoteControlRevoked(RemoteControlRevokedEvent event)
{
synchronized(videoComponentMutex)
{
if(videoComponent != null)
{
videoComponent.removeKeyListener(this);
videoComponent.removeMouseListener(this);
videoComponent.removeMouseMotionListener(this);
}
}
}
/**
* Invoked when a key has been typed.
* Sets the video displaying component for the streamed remote desktop.
*
* @param e The keyborad event.
* @param videoComponenet The video component displaying the remote desktop.
*/
public void keyTyped(KeyEvent e)
public void setVideoComponent(Component videoComponent)
{
opSetDesktopSharingClient.sendKeyboardEvent(
remoteCallPeer,
e);
synchronized(videoComponentMutex)
{
if(this.videoComponent == null)
{
// If there was no old video component and a new one is set,
// registers to the operation set.
if (videoComponent != null)
opSetDesktopSharingClient.addRemoteControlListener(this);
}
else
{
// If there was an old video component and no new one is set,
// unregisters from the operation set.
if (videoComponent == null)
{
// The remove remote control listener will also be called
// directly by the operation when the peer state change.
opSetDesktopSharingClient.removeRemoteControlListener(this);
}
}
this.videoComponent = videoComponent;
}
}
}

@ -314,10 +314,10 @@ public OneToOneCallPeerPanel(
this);
}
updateViewFromModel();
this.desktopSharingMouseAndKeyboardListener
desktopSharingMouseAndKeyboardListener
= new DesktopSharingMouseAndKeyboardListener(callPeer);
updateViewFromModel();
}
/**
@ -1367,8 +1367,8 @@ private void updateViewFromModelInEventDispatchThread()
{
// Updates video component which may listen the mouse and key
// events.
this.desktopSharingMouseAndKeyboardListener
.setVideoComponent(remoteVideo);
desktopSharingMouseAndKeyboardListener.setVideoComponent(
remoteVideo);
CallPanel callPanel = callRenderer.getCallContainer();
// The remote video has been added, then tries to display the

@ -738,7 +738,15 @@ public long getRemoteSSRC(MediaType mediaType)
return ssrc;
}
return super.getRemoteSSRC(mediaType);
/*
* XXX In the case of Jitsi VideoBridge, the super implementation of
* getRemoteSSRC(MediaType) cannot be trusted because there is a single
* VideoMediaStream with multiple ReceiveStreams.
*/
return
getPeer().isJitsiVideoBridge()
? -1
: super.getRemoteSSRC(mediaType);
}
/**
@ -774,8 +782,8 @@ public long[] getRemoteSSRCs(MediaType mediaType)
= (RawUdpTransportManager) transportManager;
ColibriConferenceIQ.Channel channel
= rawUdpTransportManager.getColibriChannel(
mediaType,
false /* remote */);
mediaType,
false /* remote */);
if (channel != null)
return channel.getSSRCs();
@ -788,7 +796,8 @@ public long[] getRemoteSSRCs(MediaType mediaType)
*/
long ssrc = super.getRemoteSSRC(mediaType);
return (ssrc == -1) ? ColibriConferenceIQ.NO_SSRCS : new long[] { ssrc };
return
(ssrc == -1) ? ColibriConferenceIQ.NO_SSRCS : new long[] { ssrc };
}
/**
@ -1231,8 +1240,8 @@ void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
{
ColibriConferenceIQ.Channel dst
= rawUdpTransportManager.getColibriChannel(
mediaType,
false /* remote */);
mediaType,
false /* remote */);
if (dst != null)
{
@ -1254,10 +1263,15 @@ void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
dst.setSSRCs(ssrcs);
if(logger.isDebugEnabled())
{
logger.debug("SSRCs changed for colibri "
+ mediaType.toString() + " channel "
+ dst.getID() + ". From: "
+ dstSsrcs + ", to: " + ssrcs);
logger.debug(
"SSRCs changed for colibri "
+ mediaType.toString()
+ " channel "
+ dst.getID()
+ " from: "
+ Arrays.toString(dstSsrcs)
+ " to: "
+ Arrays.toString(ssrcs));
}
}
}

@ -190,7 +190,7 @@ private void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
* instance which it was meant for.
*/
callJabberImpl.processColibriConferenceIQ(
conferenceIQ);
conferenceIQ);
break;
}
}

@ -533,7 +533,7 @@ public void startCandidateHarvest(
mediaTypes.add(rtpDesc);
}
}
if (mediaTypes.size() != 0)
if (!mediaTypes.isEmpty())
{
/*
* We are about to request the channel allocations for

@ -589,7 +589,7 @@ public V getProtocolProvider()
* telephony conference organized by the local user/peer utilizing the Jitsi
* VideoBridge server-side technology; otherwise, <tt>false</tt>
*/
private boolean isJitsiVideoBridge()
public final boolean isJitsiVideoBridge()
{
Call call = getCall();

Loading…
Cancel
Save