[jitsi~svn:10222] Displays a pop-up notification about the removal of an audio device only

lubomir_m at java.net lubomir_m at java.net
Fri Dec 21 23:41:52 CET 2012


Project:    jitsi
Repository: svn
Revision:   10222
Author:     lubomir_m
Date:       2012-12-21 22:41:50 UTC
Link:       

Log Message:
------------
Displays a pop-up notification about the removal of an audio device only if it used to be the active/selected one.


Revisions:
----------
10222


Modified Paths:
---------------
trunk/src/net/java/sip/communicator/impl/neomedia/AudioConfigurationPanel.java
trunk/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java
trunk/lib/installer-exclude/libjitsi.jar
trunk/src/net/java/sip/communicator/impl/neomedia/VideoConfigurationPanel.java
trunk/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java
trunk/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java
libjitsi/src/org/jitsi/impl/neomedia/device/DeviceSystem.java
libjitsi/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
trunk/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java
trunk/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java
trunk/src/net/java/sip/communicator/impl/neomedia/VideoDeviceConfigurationListener.java


Diffs:
------
Index: trunk/lib/installer-exclude/libjitsi.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java	(revision 10222)
@@ -7,6 +7,7 @@
 package net.java.sip.communicator.impl.neomedia;
 
 import java.beans.*;
+import java.util.*;
 
 import javax.media.*;
 
@@ -25,20 +26,22 @@
     extends AbstractDeviceConfigurationListener
 {
     /**
-     * The last selected capture device for which we have received an event.
+     * The last <tt>PropertyChangeEvent</tt> about an audio capture device which
+     * has been received.
      */
-    private CaptureDeviceInfo captureDevice = null;
+    private PropertyChangeEvent capturePropertyChangeEvent;
 
     /**
-     * The last selected playback device for which we have received an event.
+     * The last <tt>PropertyChangeEvent</tt> about an audio notification device
+     * which has been received.
      */
-    private CaptureDeviceInfo playbackDevice = null;
+    private PropertyChangeEvent notifyPropertyChangeEvent;
 
     /**
-     * The last selected notification device for which we have received an
-     * event.
+     * The last <tt>PropertyChangeEvent</tt> about an audio playback device
+     * which has been received.
      */
-    private CaptureDeviceInfo notificationDevice = null;
+    private PropertyChangeEvent playbackPropertyChangeEvent;
 
     /**
      * Creates a listener to the click on the popup message concerning audio
@@ -53,110 +56,177 @@
     }
 
     /**
-     * Function called when an audio device is plugged or unplugged.
+     * Notifies this instance that a property related to the configuration of
+     * devices has had its value changed and thus signals that an audio device
+     * may have been plugged or unplugged.
      *
-     * @param event The property change event which may concern the audio
-     * device.
+     * @param ev a <tt>PropertyChangeEvent</tt> which describes the name of the
+     * property whose value has changed and the old and new values of that
+     * property
      */
-    public void propertyChange(PropertyChangeEvent event)
+    public void propertyChange(PropertyChangeEvent ev)
     {
-        String popUpEvent = null;
-        String title = null;
-        CaptureDeviceInfo device = null;
-        ResourceManagementService resources
-            = NeomediaActivator.getResources();
+        String propertyName = ev.getPropertyName();
 
-        // If the device configuration has changed: a device has been
-        // plugged or un-plugged.
-        if(DeviceConfiguration.PROP_AUDIO_SYSTEM_DEVICES
-                .equals(event.getPropertyName()))
+        /*
+         * The list of available capture, notification and/or playback devices
+         * has changes.
+         */
+        if(DeviceConfiguration.PROP_AUDIO_SYSTEM_DEVICES.equals(propertyName))
         {
-            popUpEvent = NeomediaActivator.DEVICE_CONFIGURATION_HAS_CHANGED;
-            // A device has been connected.
-            if(event.getNewValue() != null)
+            @SuppressWarnings("unchecked")
+            List<CaptureDeviceInfo> oldDevices
+                = (List<CaptureDeviceInfo>) ev.getOldValue();
+            @SuppressWarnings("unchecked")
+            List<CaptureDeviceInfo> newDevices
+                = (List<CaptureDeviceInfo>) ev.getNewValue();
+
+            if (oldDevices.isEmpty())
+                oldDevices = null;
+            if (newDevices.isEmpty())
+                newDevices = null;
+
+            String title;
+            ResourceManagementService r = NeomediaActivator.getResources();
+            List<CaptureDeviceInfo> devices;
+            boolean removal;
+
+            // At least one new device has been connected.
+            if(newDevices != null)
             {
-                title = resources.getI18NString(
-                        "impl.media.configform"
-                        + ".AUDIO_DEVICE_CONNECTED");
-                device = (CaptureDeviceInfo) event.getNewValue();
+                title
+                    = r.getI18NString(
+                            "impl.media.configform.AUDIO_DEVICE_CONNECTED");
+                devices = newDevices;
+                removal = false;
             }
-            // A device has been disconnected.
-            else if(event.getOldValue() != null)
+            /*
+             * At least one old device has been disconnected and no new device
+             * has been connected.
+             */
+            else if(oldDevices != null)
             {
-                title = resources.getI18NString(
-                        "impl.media.configform"
-                        + ".AUDIO_DEVICE_DISCONNECTED");
-                device = (CaptureDeviceInfo) event.getOldValue();
+                title
+                    = r.getI18NString(
+                            "impl.media.configform.AUDIO_DEVICE_DISCONNECTED");
+                devices = oldDevices;
+                removal = true;
             }
-        }
-        // If a new capture device has been selected.
-        else if(CaptureDevices.PROP_DEVICE.equals(event.getPropertyName()))
-        {
-            if(event.getNewValue() != null)
+            else
             {
-                captureDevice = (CaptureDeviceInfo) event.getNewValue();
+                /*
+                 * Neither a new device has been connected nor an old device has
+                 * been disconnected. Why are we even here in the first place
+                 * anyway?
+                 */
+                capturePropertyChangeEvent = null;
+                notifyPropertyChangeEvent = null;
+                playbackPropertyChangeEvent = null;
+                return;
             }
-        }
-        // If a new playback device has been selected.
-        else if(PlaybackDevices.PROP_DEVICE.equals(event.getPropertyName()))
-        {
-            if(event.getNewValue() != null)
-            {
-                playbackDevice = (CaptureDeviceInfo) event.getNewValue();
-            }
-        }
-        // If a new notify device has been selected.
-        else if(NotifyDevices.PROP_DEVICE.equals(event.getPropertyName()))
-        {
-            if(event.getNewValue() != null)
-            {
-                notificationDevice = (CaptureDeviceInfo) event.getNewValue();
-            }
-        }
 
-        String body = null;
-        if(device != null)
-        {
-            body = device.getName();
-            if(captureDevice != null
-                    || playbackDevice != null
-                    || notificationDevice != null)
+            StringBuilder body = new StringBuilder();
+
+            for (CaptureDeviceInfo device : devices)
+                body.append(device.getName()).append("\r\n");
+
+            DeviceConfiguration devConf = (DeviceConfiguration) ev.getSource();
+            AudioSystem audioSystem = devConf.getAudioSystem();
+            boolean selectedHasChanged = false;
+
+            if (audioSystem != null)
             {
-                body += "\r\n";
-                if(captureDevice != null)
+                if(capturePropertyChangeEvent != null)
                 {
-                    body += "\r\n"
-                        + resources.getI18NString(
-                                "impl.media.configform"
-                                + ".AUDIO_DEVICE_SELECTED_AUDIO_IN")
-                        + "\r\n\t"
-                        + captureDevice.getName();
-                    captureDevice = null;
+                    CaptureDeviceInfo cdi
+                        = audioSystem.getDevice(AudioSystem.CAPTURE_INDEX);
+
+                    if ((cdi != null)
+                            && !cdi.equals(
+                                    capturePropertyChangeEvent.getOldValue()))
+                    {
+                        body.append("\r\n")
+                            .append(
+                                    r.getI18NString(
+                                            "impl.media.configform"
+                                                + ".AUDIO_DEVICE_SELECTED_AUDIO_IN"))
+                            .append("\r\n\t")
+                            .append(cdi.getName());
+                        selectedHasChanged = true;
+                    }
                 }
-                if(playbackDevice != null)
+                if(playbackPropertyChangeEvent != null)
                 {
-                    body += "\r\n"
-                        + resources.getI18NString(
-                                "impl.media.configform"
-                                + ".AUDIO_DEVICE_SELECTED_AUDIO_OUT")
-                        + "\r\n\t"
-                        + playbackDevice.getName();
-                    playbackDevice = null;
+                    CaptureDeviceInfo cdi
+                        = audioSystem.getDevice(AudioSystem.PLAYBACK_INDEX);
+
+                    if ((cdi != null)
+                            && !cdi.equals(
+                                    playbackPropertyChangeEvent.getOldValue()))
+                    {
+                        body.append("\r\n")
+                            .append(
+                                    r.getI18NString(
+                                            "impl.media.configform"
+                                                + ".AUDIO_DEVICE_SELECTED_AUDIO_OUT"))
+                            .append("\r\n\t")
+                            .append(cdi.getName());
+                        selectedHasChanged = true;
+                    }
                 }
-                if(notificationDevice != null)
+                if(notifyPropertyChangeEvent != null)
                 {
-                    body += "\r\n"
-                        + resources.getI18NString(
-                                "impl.media.configform"
-                                + ".AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS")
-                        + "\r\n\t"
-                        + notificationDevice.getName();
-                    notificationDevice = null;
+                    CaptureDeviceInfo cdi
+                        = audioSystem.getDevice(AudioSystem.NOTIFY_INDEX);
+
+                    if ((cdi != null)
+                            && !cdi.equals(
+                                    notifyPropertyChangeEvent.getOldValue()))
+                    {
+                        body.append("\r\n")
+                            .append(
+                                    r.getI18NString(
+                                            "impl.media.configform"
+                                                + ".AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS"))
+                            .append("\r\n\t")
+                            .append(cdi.getName());
+                        selectedHasChanged = true;
+                    }
                 }
             }
+            capturePropertyChangeEvent = null;
+            notifyPropertyChangeEvent = null;
+            playbackPropertyChangeEvent = null;
+
+            /*
+             * If an old device has been disconnected and no new device has been
+             * connected, show a notification only if any selected device has
+             * changed.
+             */
+            if (!removal || selectedHasChanged)
+            {
+                showPopUpNotification(
+                        title,
+                        body.toString(),
+                        NeomediaActivator.DEVICE_CONFIGURATION_HAS_CHANGED);
+            }
         }
-
-        // Shows the pop-up notification.
-        super.showPopUpNotification(title, body, popUpEvent);
+        /*
+         * A new capture, notification or playback devices has been selected.
+         * We will not show a notification, we will remember to report the
+         * change after the batch of changes completes.
+         */
+        else if(CaptureDevices.PROP_DEVICE.equals(propertyName))
+        {
+            capturePropertyChangeEvent = ev;
+        }
+        else if(NotifyDevices.PROP_DEVICE.equals(propertyName))
+        {
+            notifyPropertyChangeEvent = ev;
+        }
+        else if(PlaybackDevices.PROP_DEVICE.equals(propertyName))
+        {
+            playbackPropertyChangeEvent = ev;
+        }
     }
 }
Index: trunk/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java	(revision 10222)
@@ -12,10 +12,8 @@
 import net.java.sip.communicator.service.gui.*;
 import net.java.sip.communicator.service.notification.*;
 import net.java.sip.communicator.service.systray.event.*;
+import net.java.sip.communicator.util.*;
 
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
 /**
  * An abstract listener to the click on the popup message concerning
  * device configuration changes.
@@ -29,7 +27,7 @@
     /**
      *  The audio or video configuration form.
      */
-    private ConfigurationForm configurationForm;
+    private final ConfigurationForm configurationForm;
 
     /**
      * A boolean used to verify that this listener registers only once to
@@ -50,50 +48,91 @@
     }
 
     /**
-     * Registers or unregister as a popup message listener to detect when a
-     * user click on notification saying that the device configuration has
-     * changed.
+     * Adds/removes this instance as a <tt>PopupMessageListener</tt> to/from the
+     * <tt>NotificationService</tt> in order to be able to detect when the user
+     * clicks on a pop-up notification displayed by this instance.
      *
-     * @param enable True to register to the popup message notifcation
-     * handler.  False to unregister.
+     * @param add <tt>true</tt> to add this instance as a
+     * <tt>PopupMessageListener</tt> to the <tt>NotificationService</tt> or
+     * <tt>false</tt> to remove it
      */
-    public void managePopupMessageListenerRegistration(boolean enable)
+    private void addOrRemovePopupMessageListener(boolean add)
     {
-        Iterator<NotificationHandler> notificationHandlers = NeomediaActivator
-            .getNotificationService()
-            .getActionHandlers(
-                    net.java.sip.communicator.service.notification.NotificationAction.ACTION_POPUP_MESSAGE)
-            .iterator();
-        NotificationHandler notificationHandler;
+        Iterator<NotificationHandler> notificationHandlers
+            = NeomediaActivator.getNotificationService()
+                    .getActionHandlers(NotificationAction.ACTION_POPUP_MESSAGE)
+                        .iterator();
+
         while(notificationHandlers.hasNext())
         {
-            notificationHandler = notificationHandlers.next();
-            if(notificationHandler
-                    instanceof PopupMessageNotificationHandler)
+            NotificationHandler notificationHandler
+                = notificationHandlers.next();
+
+            if(notificationHandler instanceof PopupMessageNotificationHandler)
             {
-                // Register.
-                if(enable)
+                PopupMessageNotificationHandler popupMessageNotificationHandler
+                    = (PopupMessageNotificationHandler) notificationHandler;
+
+                if(add)
                 {
-                    ((PopupMessageNotificationHandler) notificationHandler)
-                        .addPopupMessageListener(this);
+                    popupMessageNotificationHandler.addPopupMessageListener(
+                            this);
                 }
-                // Unregister.
                 else
                 {
-                    ((PopupMessageNotificationHandler) notificationHandler)
-                        .removePopupMessageListener(this);
+                    popupMessageNotificationHandler.removePopupMessageListener(
+                            this);
                 }
             }
         }
     }
 
     /**
+     * Releases the resources acquired by this instance throughout its lifetime,
+     * uninstalls the listeners it has installed and, generally, prepares it for
+     * garbage collection.
+     */
+    public void dispose()
+    {
+        addOrRemovePopupMessageListener(false);
+    }
+
+    /**
+     * Indicates that user has clicked on the systray popup message.
+     * 
+     * @param ev the event triggered when user clicks on the systray popup
+     * message
+     */
+    public void popupMessageClicked(SystrayPopupMessageEvent ev)
+    {
+        // Checks if this event is fired from one click on one of our popup
+        // message.
+        if(ev.getTag() == this)
+        {
+            // Get the UI service
+            UIService uiService
+                = ServiceUtils.getService(
+                        NeomediaActivator.getBundleContext(),
+                        UIService.class);
+
+            if(uiService != null)
+            {
+                // Shows the audio configuration window.
+                ConfigurationContainer configurationContainer
+                    = uiService.getConfigurationContainer();
+
+                configurationContainer.setSelected(configurationForm);
+                configurationContainer.setVisible(true);
+            }
+        }
+    }
+
+    /**
      * Function called when an audio device is plugged or unplugged.
      *
-     * @param event The property change event which may concern the audio
-     * device.
+     * @param ev The property change event which may concern the audio device
      */
-    public abstract void propertyChange(PropertyChangeEvent event);
+    public abstract void propertyChange(PropertyChangeEvent ev);
 
     /**
      * Shows a pop-up notification corresponding to a device configuration
@@ -117,68 +156,31 @@
 
             if(notificationService != null)
             {
-                // Registers only once to the  popup message notification
+                // Registers only once to the popup message notification
                 // handler.
                 if(!isRegisteredToPopupMessageListener)
                 {
                     isRegisteredToPopupMessageListener = true;
-                    managePopupMessageListenerRegistration(true);
+                    addOrRemovePopupMessageListener(true);
                 }
 
                 // Fires the popup notification.
                 Map<String,Object> extras = new HashMap<String,Object>();
+
                 extras.put(
                         NotificationData.POPUP_MESSAGE_HANDLER_TAG_EXTRA,
                         this);
-
-                ResourceManagementService resources
-                    = NeomediaActivator.getResources();
-
                 notificationService.fireNotification(
                         popUpEvent,
                         title,
                         body
                         + "\r\n\r\n"
-                        + resources.getI18NString(
-                            "impl.media.configform"
-                            + ".AUDIO_DEVICE_CONFIG_MANAGMENT_CLICK"),
+                        + NeomediaActivator.getResources().getI18NString(
+                                "impl.media.configform"
+                                    + ".AUDIO_DEVICE_CONFIG_MANAGMENT_CLICK"),
                         null,
                         extras);
             }
         }
     }
-
-    /**
-     * Indicates that user has clicked on the systray popup message.
-     * 
-     * @param evt the event triggered when user clicks on the systray popup
-     * message
-     */
-    public void popupMessageClicked(SystrayPopupMessageEvent evt)
-    {
-        // Checks if this event is fired from one click on one of our popup
-        // message.
-        //if(evt.getTag() == audioDeviceConfigurationPropertyChangeListener)
-        if(evt.getTag() == this)
-        {
-            // Get the UI service
-            BundleContext bundleContext = NeomediaActivator.getBundleContext();
-            ServiceReference uiReference = bundleContext
-                .getServiceReference(UIService.class.getName());
-
-            UIService uiService = (UIService) bundleContext
-                .getService(uiReference);
-
-            if(uiService != null)
-            {
-                // Shows the audio configuration window.
-                ConfigurationContainer configurationContainer
-                    = uiService.getConfigurationContainer();
-                configurationContainer.setSelected(
-                        this.configurationForm);
-                        //NeomediaActivator.getAudioConfigurationForm());
-                configurationContainer.setVisible(true);
-            }
-        }
-    }
 }
Index: trunk/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java	(revision 10222)
@@ -7,7 +7,6 @@
 package net.java.sip.communicator.impl.neomedia;
 
 import java.awt.*;
-import java.awt.event.*;
 import java.beans.*;
 import java.util.*;
 import java.util.List;
@@ -32,90 +31,19 @@
                PropertyChangeListener
 {
     /**
-     * Encapsulates a <tt>CaptureDeviceInfo</tt> for the purposes of its display
-     * in the user interface.
-     */
-    public static class CaptureDevice
-    {
-        /**
-         * The encapsulated info.
-         */
-        public final CaptureDeviceInfo info;
-
-        /**
-         * Creates the wrapper.
-         * @param info the info object we wrap.
-         */
-        public CaptureDevice(CaptureDeviceInfo info)
-        {
-            this.info = info;
-        }
-
-        /**
-         * Determines whether the <tt>CaptureDeviceInfo</tt> encapsulated by
-         * this instance is equal (by value) to a specific
-         * <tt>CaptureDeviceInfo</tt>.
-         *
-         * @param cdi the <tt>CaptureDeviceInfo</tt> to be determined whether it
-         * is equal (by value) to the <tt>CaptureDeviceInfo</tt> encapsulated by
-         * this instance
-         * @return <tt>true</tt> if the <tt>CaptureDeviceInfo</tt> encapsulated
-         * by this instance is equal (by value) to the specified <tt>cdi</tt>;
-         * otherwise, <tt>false</tt>
-         */
-        public boolean equals(CaptureDeviceInfo cdi)
-        {
-            return (info == null) ? (cdi == null) : info.equals(cdi);
-        }
-
-        /**
-         * Gets a human-readable <tt>String</tt> representation of this
-         * instance.
-         *
-         * @return a <tt>String</tt> value which is a human-readable
-         * representation of this instance
-         */
-        @Override
-        public String toString()
-        {
-            String s;
-
-            if(info == null)
-            {
-                s
-                    = NeomediaActivator.getResources().getI18NString(
-                            "impl.media.configform.NO_DEVICE");
-            }
-            else
-            {
-                s = info.getName();
-                if(info instanceof ExtendedCaptureDeviceInfo)
-                {
-                    String transportType
-                        = ((ExtendedCaptureDeviceInfo) info).getTransportType();
-
-                    if(transportType != null)
-                        s += " (" + transportType + ")";
-                }
-            }
-            return s;
-        }
-    }
-
-    /**
      * Type of the model - audio.
      */
     public static final int AUDIO = 1;
 
     /**
-     * Type of the model - video.
+     * Audio Capture Device.
      */
-    public static final int VIDEO = 2;
+    public static final int AUDIO_CAPTURE = 3;
 
     /**
-     * Audio Capture Device.
+     * Audio device for notification sounds.
      */
-    public static final int AUDIO_CAPTURE = 3;
+    public static final int AUDIO_NOTIFY = 5;
 
     /**
      * Audio playback device.
@@ -123,9 +51,9 @@
     public static final int AUDIO_PLAYBACK = 4;
 
     /**
-     * Audio device for notification sounds.
+     * Type of the model - video.
      */
-    public static final int AUDIO_NOTIFY = 5;
+    public static final int VIDEO = 2;
 
     private AudioSystem[] audioSystems;
 
@@ -151,11 +79,6 @@
     private final int type;
 
     /**
-     * The parent component.
-     */
-    private Component parent;
-
-    /**
      * Creates device combobox model
      * @param parent the parent component
      * @param deviceConfiguration the current device configuration
@@ -175,7 +98,6 @@
                 && (type != VIDEO))
             throw new IllegalArgumentException("type");
 
-        this.parent = parent;
         this.deviceConfiguration = deviceConfiguration;
         this.type = type;
 
@@ -287,6 +209,14 @@
         return devices;
     }
 
+    public Object getElementAt(int index)
+    {
+        if (type == AUDIO)
+            return getAudioSystems()[index];
+        else
+            return getDevices()[index];
+    }
+
     /**
      * Extracts the devices selected by the configuration.
      * @return <tt>CaptureDevice</tt> selected
@@ -331,14 +261,6 @@
         return null;
     }
 
-    public Object getElementAt(int index)
-    {
-        if (type == AUDIO)
-            return getAudioSystems()[index];
-        else
-            return getDevices()[index];
-    }
-
     public Object getSelectedItem()
     {
         if (type == AUDIO)
@@ -355,6 +277,39 @@
             return getDevices().length;
     }
 
+    /**
+     * Notifies this instance about changes in the values of the properties of
+     * {@link #deviceConfiguration} so that this instance keeps itself
+     * up-to-date with respect to the list of devices.
+     *
+     * @param ev a <tt>PropertyChangeEvent</tt> which describes the name of the
+     * property whose value has changed and the old and new values of that
+     * property
+     */
+    public void propertyChange(final PropertyChangeEvent ev)
+    {
+        if(DeviceConfiguration.PROP_AUDIO_SYSTEM_DEVICES.equals(
+                ev.getPropertyName()))
+        {
+            if(SwingUtilities.isEventDispatchThread())
+            {
+                devices = null;
+                fireContentsChanged(0, getSize() - 1);
+            }
+            else
+            {
+                SwingUtilities.invokeLater(
+                        new Runnable()
+                        {
+                            public void run()
+                            {
+                                propertyChange(ev);
+                            }
+                        });
+            }
+        }
+    }
+
     public void removeListDataListener(ListDataListener listener)
     {
         if (listener == null)
@@ -437,30 +392,73 @@
     }
 
     /**
-     * We listen for changes in the devices in order to update the list
-     * of devices we show.
-     * @param event the event.
+     * Encapsulates a <tt>CaptureDeviceInfo</tt> for the purposes of its display
+     * in the user interface.
      */
-    public void propertyChange(final PropertyChangeEvent event)
+    public static class CaptureDevice
     {
-        if(DeviceConfiguration.PROP_AUDIO_SYSTEM_DEVICES.equals(
-                event.getPropertyName()))
+        /**
+         * The encapsulated info.
+         */
+        public final CaptureDeviceInfo info;
+
+        /**
+         * Creates the wrapper.
+         * @param info the info object we wrap.
+         */
+        public CaptureDevice(CaptureDeviceInfo info)
         {
-            if(!SwingUtilities.isEventDispatchThread())
+            this.info = info;
+        }
+
+        /**
+         * Determines whether the <tt>CaptureDeviceInfo</tt> encapsulated by
+         * this instance is equal (by value) to a specific
+         * <tt>CaptureDeviceInfo</tt>.
+         *
+         * @param cdi the <tt>CaptureDeviceInfo</tt> to be determined whether it
+         * is equal (by value) to the <tt>CaptureDeviceInfo</tt> encapsulated by
+         * this instance
+         * @return <tt>true</tt> if the <tt>CaptureDeviceInfo</tt> encapsulated
+         * by this instance is equal (by value) to the specified <tt>cdi</tt>;
+         * otherwise, <tt>false</tt>
+         */
+        public boolean equals(CaptureDeviceInfo cdi)
+        {
+            return (info == null) ? (cdi == null) : info.equals(cdi);
+        }
+
+        /**
+         * Gets a human-readable <tt>String</tt> representation of this
+         * instance.
+         *
+         * @return a <tt>String</tt> value which is a human-readable
+         * representation of this instance
+         */
+        @Override
+        public String toString()
+        {
+            String s;
+
+            if(info == null)
             {
-                SwingUtilities.invokeLater(
-                    new Runnable()
-                    {
-                        public void run()
-                        {
-                            propertyChange(event);
-                        }
-                    });
-                return;
+                s
+                    = NeomediaActivator.getResources().getI18NString(
+                            "impl.media.configform.NO_DEVICE");
             }
+            else
+            {
+                s = info.getName();
+                if(info instanceof ExtendedCaptureDeviceInfo)
+                {
+                    String transportType
+                        = ((ExtendedCaptureDeviceInfo) info).getTransportType();
 
-            devices = null;
-            fireContentsChanged(0, getSize() - 1);
+                    if(transportType != null)
+                        s += " (" + transportType + ")";
+                }
+            }
+            return s;
         }
     }
 }
Index: trunk/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java	(revision 10222)
@@ -32,11 +32,6 @@
                DocumentListener
 {
     /**
-     * Serial version UID.
-     */
-    private static final long serialVersionUID = 0L;
-
-    /**
      * The <tt>Logger</tt> used by the <tt>CallRecordingConfigForm</tt> class
      * and its instances for logging output.
      */
@@ -50,22 +45,27 @@
         = NeomediaActivator.getResources();
 
     /**
-     * Directory where calls are stored. Default is SC_HOME/calls.
+     * Serial version UID.
      */
-    private String savedCallsDir;
+    private static final long serialVersionUID = 0L;
 
     /**
-     * Directory choose dialog.
+     * UI components.
      */
-    private final SipCommFileChooser dirChooser;
+    private JButton callDirChooseButton;
 
+    private JTextField callDirTextField;
+
     /**
-     * UI components.
+     * Directory choose dialog.
      */
-    private JButton callDirChooseButton;
-    private JTextField callDirTextField;
+    private final SipCommFileChooser dirChooser;
     private JComboBox formatsComboBox;
     private JCheckBox saveCallsToCheckBox;
+    /**
+     * Directory where calls are stored. Default is SC_HOME/calls.
+     */
+    private String savedCallsDir;
 
     /**
      * Creates an instance of the <tt>CallConfigurationPanel</tt>.
@@ -89,110 +89,6 @@
     }
 
     /**
-     * Loads values from the configuration and sets the UI components to these
-     * values.
-     */
-    private void loadValues()
-    {
-        ConfigurationService configuration
-            = NeomediaActivator.getConfigurationService();
-        String format = configuration.getString(Recorder.FORMAT);
-
-        formatsComboBox.setSelectedItem(
-                (format == null)
-                    ? SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT
-                    : format);
-
-        savedCallsDir = configuration.getString(Recorder.SAVED_CALLS_PATH);
-        saveCallsToCheckBox.setSelected(savedCallsDir != null);
-        callDirTextField.setText(savedCallsDir);
-        callDirTextField.setEnabled(saveCallsToCheckBox.isSelected());
-        callDirTextField.getDocument().addDocumentListener(this);
-        callDirChooseButton.setEnabled(saveCallsToCheckBox.isSelected());
-    }
-
-    /**
-     * Creates a panel with call management components.
-     */
-    private void initComponents()
-    {
-        // labels panel
-        JPanel labelsPanel = new TransparentPanel(new GridLayout(2, 1));
-        JLabel formatsLabel
-            = new JLabel(
-                    resources.getI18NString(
-                            "plugin.callrecordingconfig.SUPPORTED_FORMATS"));
-
-        saveCallsToCheckBox
-            = new SIPCommCheckBox(
-                    resources.getI18NString(
-                            "plugin.callrecordingconfig.SAVE_CALLS"));
-        saveCallsToCheckBox.addActionListener(this);
-
-        labelsPanel.add(formatsLabel);
-        labelsPanel.add(saveCallsToCheckBox);
-
-        // saved calls directory panel
-        JPanel callDirPanel = new TransparentPanel(new BorderLayout());
-
-        callDirTextField = new JTextField();
-        callDirTextField.addActionListener(this);
-        callDirPanel.add(callDirTextField);
-
-        callDirChooseButton
-            = new JButton(
-                    new ImageIcon(
-                            resources.getImageInBytes(
-                                    "plugin.notificationconfig.FOLDER_ICON")));
-
-        callDirChooseButton.addActionListener(this);
-        callDirPanel.add(callDirChooseButton, BorderLayout.EAST);
-
-        // values panel
-        JPanel valuesPanel = new TransparentPanel(new GridLayout(2, 1));
-
-        valuesPanel.add(createFormatsComboBox());
-        valuesPanel.add(callDirPanel);
-
-        // main panel
-        JPanel mainPanel = new TransparentPanel(new BorderLayout());
-
-        mainPanel.add(labelsPanel, BorderLayout.WEST);
-        mainPanel.add(valuesPanel, BorderLayout.CENTER);
-
-        this.add(mainPanel, BorderLayout.NORTH);
-    }
-
-    /**
-     * Creates a combo box with supported audio formats.
-     *
-     * @return a combo box with supported audio formats
-     */
-    private Component createFormatsComboBox()
-    {
-        ComboBoxModel formatsComboBoxModel
-            = new DefaultComboBoxModel(RecorderImpl.SUPPORTED_FORMATS);
-
-        formatsComboBox = new JComboBox();
-        formatsComboBox.setPreferredSize(new Dimension(200, 30));
-        formatsComboBox.setModel(formatsComboBoxModel);
-
-        formatsComboBox.addItemListener(new ItemListener()
-        {
-            public void itemStateChanged(ItemEvent event)
-            {
-                if (event.getStateChange() == ItemEvent.SELECTED)
-                {
-                    NeomediaActivator
-                        .getConfigurationService()
-                            .setProperty(Recorder.FORMAT, event.getItem());
-                }
-            }
-        });
-        return formatsComboBox;
-    }
-
-    /**
      * Indicates that one of the contained in this panel components has
      * performed an action.
      *
@@ -275,6 +171,94 @@
     }
 
     /**
+     * Not used.
+     *
+     * @param e the document event
+     */
+    public void changedUpdate(DocumentEvent e){}
+
+    /**
+     * Creates a combo box with supported audio formats.
+     *
+     * @return a combo box with supported audio formats
+     */
+    private Component createFormatsComboBox()
+    {
+        ComboBoxModel formatsComboBoxModel
+            = new DefaultComboBoxModel(RecorderImpl.SUPPORTED_FORMATS);
+
+        formatsComboBox = new JComboBox();
+        formatsComboBox.setPreferredSize(new Dimension(200, 30));
+        formatsComboBox.setModel(formatsComboBoxModel);
+
+        formatsComboBox.addItemListener(new ItemListener()
+        {
+            public void itemStateChanged(ItemEvent event)
+            {
+                if (event.getStateChange() == ItemEvent.SELECTED)
+                {
+                    NeomediaActivator
+                        .getConfigurationService()
+                            .setProperty(Recorder.FORMAT, event.getItem());
+                }
+            }
+        });
+        return formatsComboBox;
+    }
+
+    /**
+     * Creates a panel with call management components.
+     */
+    private void initComponents()
+    {
+        // labels panel
+        JPanel labelsPanel = new TransparentPanel(new GridLayout(2, 1));
+        JLabel formatsLabel
+            = new JLabel(
+                    resources.getI18NString(
+                            "plugin.callrecordingconfig.SUPPORTED_FORMATS"));
+
+        saveCallsToCheckBox
+            = new SIPCommCheckBox(
+                    resources.getI18NString(
+                            "plugin.callrecordingconfig.SAVE_CALLS"));
+        saveCallsToCheckBox.addActionListener(this);
+
+        labelsPanel.add(formatsLabel);
+        labelsPanel.add(saveCallsToCheckBox);
+
+        // saved calls directory panel
+        JPanel callDirPanel = new TransparentPanel(new BorderLayout());
+
+        callDirTextField = new JTextField();
+        callDirTextField.addActionListener(this);
+        callDirPanel.add(callDirTextField);
+
+        callDirChooseButton
+            = new JButton(
+                    new ImageIcon(
+                            resources.getImageInBytes(
+                                    "plugin.notificationconfig.FOLDER_ICON")));
+
+        callDirChooseButton.addActionListener(this);
+        callDirPanel.add(callDirChooseButton, BorderLayout.EAST);
+
+        // values panel
+        JPanel valuesPanel = new TransparentPanel(new GridLayout(2, 1));
+
+        valuesPanel.add(createFormatsComboBox());
+        valuesPanel.add(callDirPanel);
+
+        // main panel
+        JPanel mainPanel = new TransparentPanel(new BorderLayout());
+
+        mainPanel.add(labelsPanel, BorderLayout.WEST);
+        mainPanel.add(valuesPanel, BorderLayout.CENTER);
+
+        this.add(mainPanel, BorderLayout.NORTH);
+    }
+
+    /**
      * Gives notification that there was an insert into the document. The
      * range given by the DocumentEvent bounds the freshly inserted region.
      *
@@ -288,6 +272,29 @@
     }
 
     /**
+     * Loads values from the configuration and sets the UI components to these
+     * values.
+     */
+    private void loadValues()
+    {
+        ConfigurationService configuration
+            = NeomediaActivator.getConfigurationService();
+        String format = configuration.getString(Recorder.FORMAT);
+
+        formatsComboBox.setSelectedItem(
+                (format == null)
+                    ? SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT
+                    : format);
+
+        savedCallsDir = configuration.getString(Recorder.SAVED_CALLS_PATH);
+        saveCallsToCheckBox.setSelected(savedCallsDir != null);
+        callDirTextField.setText(savedCallsDir);
+        callDirTextField.setEnabled(saveCallsToCheckBox.isSelected());
+        callDirTextField.getDocument().addDocumentListener(this);
+        callDirChooseButton.setEnabled(saveCallsToCheckBox.isSelected());
+    }
+
+    /**
      * Gives notification that a portion of the document has been
      * removed.  The range is given in terms of what the view last
      * saw (that is, before updating sticky positions).
@@ -300,11 +307,4 @@
         if(insertedFile.exists())
             changeCallsDir(insertedFile, false);
     }
-
-    /**
-     * Not used.
-     *
-     * @param e the document event
-     */
-    public void changedUpdate(DocumentEvent e){}
 }
Index: trunk/src/net/java/sip/communicator/impl/neomedia/VideoDeviceConfigurationListener.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/VideoDeviceConfigurationListener.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/VideoDeviceConfigurationListener.java	(revision 10222)
@@ -13,11 +13,11 @@
 import net.java.sip.communicator.service.gui.*;
 
 import org.jitsi.impl.neomedia.device.*;
-import org.jitsi.service.resources.*;
 
 /**
- * A listener to the click on the popup message concerning video
- * device configuration changes.
+ * Implements a listener which responds to changes in the video device
+ * configuration by displaying pop-up notifications summarizing the changes for
+ * the user.
  *
  * @author Vincent Lucas
  */
@@ -37,40 +37,32 @@
     }
 
     /**
-     * Function called when an audio device is plugged or unplugged.
+     * Notifies this instance that a property related to the configuration of
+     * devices has had its value changed and thus signals that a video device
+     * may have been plugged or unplugged.
      *
-     * @param event The property change event which may concern the audio
-     * device.
+     * @param ev a <tt>PropertyChangeEvent</tt> which describes the name of the
+     * property whose value has changed and the old and new values of that
+     * property
      */
-    public void propertyChange(PropertyChangeEvent event)
+    public void propertyChange(PropertyChangeEvent ev)
     {
-        String popUpEvent = null;
-        String title = null;
-        CaptureDeviceInfo device = null;
-        ResourceManagementService resources
-            = NeomediaActivator.getResources();
-
         // If a new video device has been selected.
-        if(DeviceConfiguration.VIDEO_CAPTURE_DEVICE
-                .equals(event.getPropertyName()))
+        if(DeviceConfiguration.VIDEO_CAPTURE_DEVICE.equals(
+                ev.getPropertyName()))
         {
-            if(event.getNewValue() != null)
+            Object newValue = ev.getNewValue();
+
+            if(newValue != null)
             {
-                popUpEvent = NeomediaActivator.NEW_SELECTED_DEVICE;
-                title = resources.getI18NString(
-                        "impl.media.configform"
-                        + ".VIDEO_DEVICE_SELECTED");
-                device = (CaptureDeviceInfo) event.getNewValue();
+                String title
+                    = NeomediaActivator.getResources().getI18NString(
+                            "impl.media.configform.VIDEO_DEVICE_SELECTED");
+                String body = ((CaptureDeviceInfo) newValue).getName();
+                String popUpEvent = NeomediaActivator.NEW_SELECTED_DEVICE;
+
+                showPopUpNotification(title, body, popUpEvent);
             }
         }
-
-        String body = null;
-        if(device != null)
-        {
-            body = device.getName();
-        }
-
-        // Shows the pop-up notification.
-        this.showPopUpNotification(title, body, popUpEvent);
     }
 }
Index: trunk/src/net/java/sip/communicator/impl/neomedia/AudioConfigurationPanel.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/AudioConfigurationPanel.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/AudioConfigurationPanel.java	(revision 10222)
@@ -8,7 +8,6 @@
 import java.awt.*;
 
 import net.java.sip.communicator.util.swing.*;
-import org.jitsi.service.neomedia.*;
 
 /**
  * The audio configuration form.
@@ -29,8 +28,10 @@
     public AudioConfigurationPanel()
     {
         super(new BorderLayout());
-        MediaConfigurationService mediaConfiguration
-                = NeomediaActivator.getMediaConfiguration();
-        add(mediaConfiguration.createAudioConfigPanel(), BorderLayout.NORTH);
+
+        add(
+                NeomediaActivator.getMediaConfiguration()
+                        .createAudioConfigPanel(),
+                BorderLayout.NORTH);
     }
 }
Index: trunk/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java
===================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java	(revision 10221)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java	(revision 10222)
@@ -37,12 +37,6 @@
 {
 
     /**
-     * The <tt>Logger</tt> used by the <tt>NeomediaActivator</tt> class and its
-     * instances for logging output.
-     */
-    private final Logger logger = Logger.getLogger(NeomediaActivator.class);
-
-    /**
      * Indicates if the audio configuration form should be disabled, i.e.
      * not visible to the user.
      */
@@ -50,25 +44,21 @@
         = "net.java.sip.communicator.impl.neomedia.AUDIO_CONFIG_DISABLED";
 
     /**
-     * Indicates if the video configuration form should be disabled, i.e.
-     * not visible to the user.
+     *  The audio configuration form used to define the capture/notify/playback
+     *  audio devices.
      */
-    private static final String VIDEO_CONFIG_DISABLED_PROP
-        = "net.java.sip.communicator.impl.neomedia.VIDEO_CONFIG_DISABLED";
+    private static ConfigurationForm audioConfigurationForm;
 
     /**
-     * Indicates if the H.264 configuration form should be disabled, i.e.
-     * not visible to the user.
+     * The audio notifier service.
      */
-    private static final String H264_CONFIG_DISABLED_PROP
-        = "net.java.sip.communicator.impl.neomedia.h264config.DISABLED";
+    private static AudioNotifierService audioNotifierService;
 
     /**
-     * Indicates if the ZRTP configuration form should be disabled, i.e.
-     * not visible to the user.
+     * The context in which the one and only <tt>NeomediaActivator</tt> instance
+     * has started executing.
      */
-    private static final String ZRTP_CONFIG_DISABLED_PROP
-        = "net.java.sip.communicator.impl.neomedia.zrtpconfig.DISABLED";
+    private static BundleContext bundleContext;
 
     /**
      * Indicates if the call recording config form should be disabled, i.e.
@@ -78,6 +68,13 @@
         = "net.java.sip.communicator.impl.neomedia.callrecordingconfig.DISABLED";
 
     /**
+     * The <tt>ConfigurationService</tt> registered in {@link #bundleContext}
+     * and used by the <tt>NeomediaActivator</tt> instance to read and write
+     * configuration properties.
+     */
+    private static ConfigurationService configurationService;
+
+    /**
      * The name of the notification pop-up event displayed when the device
      * configration has changed.
      */
@@ -85,41 +82,46 @@
         = "DeviceConfigurationChanged";
 
     /**
-     * The name of the notification pop-up event displayed when a new device
-     * is selected (for audio in, audio out or notifications).
+     * The <tt>FileAccessService</tt> registered in {@link #bundleContext} and
+     * used by the <tt>NeomediaActivator</tt> instance to safely access files.
      */
-    public static final String NEW_SELECTED_DEVICE
-        = "NewSelectedDevice";
+    private static FileAccessService fileAccessService;
 
     /**
-     * The context in which the one and only <tt>NeomediaActivator</tt> instance
-     * has started executing.
+     * Indicates if the H.264 configuration form should be disabled, i.e.
+     * not visible to the user.
      */
-    private static BundleContext bundleContext;
+    private static final String H264_CONFIG_DISABLED_PROP
+        = "net.java.sip.communicator.impl.neomedia.h264config.DISABLED";
 
     /**
-     * The <tt>ConfigurationService</tt> registered in {@link #bundleContext}
-     * and used by the <tt>NeomediaActivator</tt> instance to read and write
-     * configuration properties.
+     * A {@link MediaConfigurationService} instance.
      */
-    private static ConfigurationService configurationService;
+    private static MediaConfigurationImpl mediaConfiguration;
 
     /**
-     * The <tt>FileAccessService</tt> registered in {@link #bundleContext} and
-     * used by the <tt>NeomediaActivator</tt> instance to safely access files.
+     * The one and only <tt>MediaServiceImpl</tt> instance registered in
+     * {@link #bundleContext} by the <tt>NeomediaActivator</tt> instance.
      */
-    private static FileAccessService fileAccessService;
+    private static MediaServiceImpl mediaServiceImpl;
 
     /**
+     * The name of the notification pop-up event displayed when a new device
+     * is selected (for audio in, audio out or notifications).
+     */
+    public static final String NEW_SELECTED_DEVICE
+        = "NewSelectedDevice";
+
+    /**
      * The notifcation service to pop-up messages.
      */
     private static NotificationService notificationService;
 
     /**
-     * The one and only <tt>MediaServiceImpl</tt> instance registered in
-     * {@link #bundleContext} by the <tt>NeomediaActivator</tt> instance.
+     * The OSGi <tt>PacketLoggingService</tt> of {@link #mediaServiceImpl} in
+     * {@link #bundleContext} and used for debugging.
      */
-    private static MediaServiceImpl mediaServiceImpl;
+    private static PacketLoggingService packetLoggingService  = null;
 
     /**
      * The <tt>ResourceManagementService</tt> registered in
@@ -130,19 +132,13 @@
     private static ResourceManagementService resources;
 
     /**
-     * The OSGi <tt>PacketLoggingService</tt> of {@link #mediaServiceImpl} in
-     * {@link #bundleContext} and used for debugging.
+     * Indicates if the video configuration form should be disabled, i.e.
+     * not visible to the user.
      */
-    private static PacketLoggingService packetLoggingService  = null;
+    private static final String VIDEO_CONFIG_DISABLED_PROP
+        = "net.java.sip.communicator.impl.neomedia.VIDEO_CONFIG_DISABLED";
 
     /**
-     *  A listener to the click on the popup message concerning audio device
-     *  configuration changes.
-     */
-    private AudioDeviceConfigurationListener
-        audioDeviceConfigurationPropertyChangeListener;
-
-    /**
      *  A listener to the click on the popup message concerning video device
      *  configuration changes.
      *  Disabled until video hotplug is not available.
@@ -151,27 +147,22
[truncated due to length]





More information about the commits mailing list