- Fixes the Eclipse .classpath of libjitsi which was broken because of the change of the JSON implementation library.

- Fixes a call-related memory leak.
cusax-fix
Lyubomir Marinov 14 years ago
parent f87c4cf9ba
commit 1e258ced34

@ -7,11 +7,13 @@
package net.java.sip.communicator.service.protocol.media;
import java.beans.*;
import java.lang.ref.*;
import java.util.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.device.*;
import org.jitsi.util.*;
import org.jitsi.util.event.*;
import net.java.sip.communicator.service.protocol.*;
@ -25,6 +27,13 @@
public class MediaAwareCallConference
extends CallConference
{
/**
* The <tt>PropertyChangeListener</tt> which will listen to the
* <tt>MediaService</tt> about <tt>PropertyChangeEvent</tt>s.
*/
private static WeakPropertyChangeListener
mediaServicePropertyChangeListener;
/**
* The <tt>MediaDevice</tt>s indexed by <tt>MediaType</tt> ordinal which are
* to be used by this telephony conference for media capture and/or
@ -47,12 +56,12 @@ public class MediaAwareCallConference
*/
private final PropertyChangeListener propertyChangeListener
= new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent event)
{
MediaAwareCallConference.this.propertyChange(event);
}
};
{
public void propertyChange(PropertyChangeEvent ev)
{
MediaAwareCallConference.this.propertyChange(ev);
}
};
/**
* The <tt>RTPTranslator</tt> which forwards video RTP and RTCP traffic
@ -92,8 +101,49 @@ public MediaAwareCallConference(boolean jitsiVideoBridge)
* Listen to the MediaService in order to reflect changes in the user's
* selection with respect to the default media device.
*/
ProtocolMediaActivator.getMediaService().addPropertyChangeListener(
propertyChangeListener);
addMediaServicePropertyChangeListener(propertyChangeListener);
}
/**
* Adds a specific <tt>PropertyChangeListener</tt> to be notified about
* <tt>PropertyChangeEvent</tt>s fired by the current <tt>MediaService</tt>
* implementation. The implementation adds a <tt>WeakReference</tt> to the
* specified <tt>listener</tt> because <tt>MediaAwareCallConference</tt>
* is unable to determine when the <tt>PropertyChangeListener</tt> is to be
* removed.
*
* @param listener the <tt>PropertyChangeListener</tt> to add
*/
private static synchronized void addMediaServicePropertyChangeListener(
PropertyChangeListener listener)
{
if (mediaServicePropertyChangeListener == null)
{
final MediaService mediaService
= ProtocolMediaActivator.getMediaService();
if (mediaService != null)
{
mediaServicePropertyChangeListener
= new WeakPropertyChangeListener()
{
protected void addThisToNotifier()
{
mediaService.addPropertyChangeListener(this);
}
protected void removeThisFromNotifier()
{
mediaService.removePropertyChangeListener(this);
}
};
}
}
if (mediaServicePropertyChangeListener != null)
{
mediaServicePropertyChangeListener.addPropertyChangeListener(
listener);
}
}
/**
@ -103,6 +153,7 @@ public MediaAwareCallConference(boolean jitsiVideoBridge)
* not being such, disposes of the mixers used by this instance when it was
* a conference focus
*/
@Override
protected void conferenceFocusChanged(boolean oldValue, boolean newValue)
{
/*
@ -243,17 +294,17 @@ public RTPTranslator getRTPTranslator(MediaType mediaType)
* {@link MediaService#DEFAULT_DEVICE} which represents the user's choice
* with respect to the default audio device.
*
* @param event a <tt>PropertyChangeEvent</tt> which specifies the name of
* the property which had its value changed and the old and new values of
* that property
* @param ev a <tt>PropertyChangeEvent</tt> which specifies the name of the
* property which had its value changed and the old and new values of that
* property
*/
private void propertyChange(PropertyChangeEvent event)
private void propertyChange(PropertyChangeEvent ev)
{
String propertyName = event.getPropertyName();
String propertyName = ev.getPropertyName();
if (MediaService.DEFAULT_DEVICE.equals(propertyName))
{
Object source = event.getSource();
Object source = ev.getSource();
if (source instanceof MediaService)
{
@ -332,4 +383,183 @@ void setDevice(MediaType mediaType, MediaDevice device)
oldValue, newValue);
}
}
/**
* Implements a <tt>PropertyChangeListener</tt> which weakly references and
* delegates to specific <tt>PropertyChangeListener</tt>s and automatically
* adds itself to and removes itself from a specific
* <tt>PropertyChangeNotifier</tt> depending on whether there are
* <tt>PropertyChangeListener</tt>s to delegate to. Thus enables listening
* to a <tt>PropertyChangeNotifier</tt> by invoking
* {@link PropertyChangeNotifier#addPropertyChangeListener(
* PropertyChangeListener)} without
* {@link PropertyChangeNotifier#removePropertyChangeListener(
* PropertyChangeListener)}.
*/
private static class WeakPropertyChangeListener
implements PropertyChangeListener
{
/**
* The indicator which determines whether this
* <tt>PropertyChangeListener</tt> has been added to {@link #notifier}.
*/
private boolean added = false;
/**
* The list of <tt>PropertyChangeListener</tt>s which are to be notified
* about <tt>PropertyChangeEvent</tt>s fired by {@link #notifier}.
*/
private final List<WeakReference<PropertyChangeListener>> listeners
= new LinkedList<WeakReference<PropertyChangeListener>>();
/**
* The <tt>PropertyChangeNotifier</tt> this instance is to listen to
* about <tt>PropertyChangeEvent</tt>s which are to be forwarded to
* {@link #listeners}.
*/
private final PropertyChangeNotifier notifier;
/**
* Initializes a new <tt>WeakPropertyChangeListener</tt> instance.
*/
protected WeakPropertyChangeListener()
{
this(null);
}
/**
* Initializes a new <tt>WeakPropertyChangeListener</tt> instance which
* is to listen to a specific <tt>PropertyChangeNotifier</tt>.
*
* @param notifier the <tt>PropertyChangeNotifier</tt> the new instance
* is to listen to
*/
public WeakPropertyChangeListener(PropertyChangeNotifier notifier)
{
this.notifier = notifier;
}
/**
* Adds a specific <tt>PropertyChangeListener</tt> to the list of
* <tt>PropertyChangeListener</tt>s to be notified about
* <tt>PropertyChangeEvent</tt>s fired by the
* <tt>PropertyChangeNotifier</tt> associated with this instance.
*
* @param listener the <tt>PropertyChangeListener</tt> to add
*/
public synchronized void addPropertyChangeListener(
PropertyChangeListener listener)
{
Iterator<WeakReference<PropertyChangeListener>> i
= listeners.iterator();
boolean add = true;
while (i.hasNext())
{
PropertyChangeListener l = i.next().get();
if (l == null)
i.remove();
else if (l.equals(listener))
add = false;
}
if (add
&& listeners.add(
new WeakReference<PropertyChangeListener>(listener))
&& !this.added)
{
addThisToNotifier();
this.added = true;
}
}
/**
* Adds this as a <tt>PropertyChangeListener</tt> to {@link #notifier}.
*/
protected void addThisToNotifier()
{
if (notifier != null)
notifier.addPropertyChangeListener(this);
}
/**
* {@inheritDoc}
*
* Notifies this instance about a <tt>PropertyChangeEvent</tt> fired by
* {@link #notifier}.
*/
public void propertyChange(PropertyChangeEvent ev)
{
PropertyChangeListener[] ls;
int n;
synchronized (this)
{
Iterator<WeakReference<PropertyChangeListener>> i
= listeners.iterator();
ls = new PropertyChangeListener[listeners.size()];
n = 0;
while (i.hasNext())
{
PropertyChangeListener l = i.next().get();
if (l == null)
i.remove();
else
ls[n++] = l;
}
if ((n == 0) && this.added)
{
removeThisFromNotifier();
this.added = false;
}
}
if (n != 0)
{
for (PropertyChangeListener l : ls)
l.propertyChange(ev);
}
}
/**
* Removes a specific <tt>PropertyChangeListener</tt> from the list of
* <tt>PropertyChangeListener</tt>s to be notified about
* <tt>PropertyChangeEvent</tt>s fired by the
* <tt>PropertyChangeNotifier</tt> associated with this instance.
*
* @param listener the <tt>PropertyChangeListener</tt> to remove
*/
@SuppressWarnings("unused")
public synchronized void removePropertyChangeListener(
PropertyChangeListener listener)
{
Iterator<WeakReference<PropertyChangeListener>> i
= listeners.iterator();
while (i.hasNext())
{
PropertyChangeListener l = i.next().get();
if ((l == null) || l.equals(listener))
i.remove();
}
if (this.added && (listeners.size() == 0))
{
removeThisFromNotifier();
this.added = false;
}
}
/**
* Removes this as a <tt>PropertyChangeListener</tt> from
* {@link #notifier}.
*/
protected void removeThisFromNotifier()
{
if (notifier != null)
notifier.removePropertyChangeListener(this);
}
}
}

Loading…
Cancel
Save