aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2012-10-18 18:36:58 +0000
committerYana Stamcheva <yana@jitsi.org>2012-10-18 18:36:58 +0000
commit442499001735288fd3906ed77146a45416608d50 (patch)
treeb1266bdbc2535ffbc6918378b1feaa3ce65d7069 /src/net/java/sip/communicator
parent0951e5bcbdfc57b1059482415931e3b6f14e62e3 (diff)
downloadjitsi-442499001735288fd3906ed77146a45416608d50.zip
jitsi-442499001735288fd3906ed77146a45416608d50.tar.gz
jitsi-442499001735288fd3906ed77146a45416608d50.tar.bz2
Adds a separate video bridge menu in Tools and adds an OperationSetVideBridge that gives access to the video bridge conference calls.
Diffstat (limited to 'src/net/java/sip/communicator')
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallManager.java156
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java12
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java237
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/menus/ToolsMenu.java218
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java106
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java6
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetVideoBridge.java62
7 files changed, 668 insertions, 129 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
index 3110e3e..dd19e3e 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
@@ -957,6 +957,34 @@ public class CallManager
}
/**
+ * Asynchronously creates a new video bridge conference <tt>Call</tt> with
+ * a specific list of participants/callees.
+ *
+ * @param callees the list of participants/callees to invite to the
+ * newly-created video bridge conference <tt>Call</tt>
+ */
+ public static void createVideoBridgeConfCall(
+ ProtocolProviderService callProvider,
+ String[] callees)
+ {
+ new InviteToConferenceBridgeThread(callProvider, callees, null).start();
+ }
+
+ /**
+ * Invites the given list of <tt>callees</tt> to the given conference
+ * <tt>call</tt>.
+ *
+ * @param callees the list of contacts to invite
+ * @param call the protocol provider to which this call belongs
+ */
+ public static void inviteToVideoBridgeConfCall(String[] callees, Call call)
+ {
+ new InviteToConferenceBridgeThread( call.getProtocolProvider(),
+ callees,
+ call).start();
+ }
+
+ /**
* Puts on or off hold the given <tt>callPeer</tt>.
* @param callPeer the peer to put on/off hold
* @param isOnHold indicates the action (on hold or off hold)
@@ -1978,63 +2006,9 @@ public class CallManager
@Override
public void run()
{
- CallConference conference;
-
- if (call == null)
- {
- conference = null;
-
- /*
- * FIXME Autmagically choose whether the Jitsi VideoBridge
- * server-side telephony conferencing technology is to be
- * utilized.
- */
- if (callees.size() == 1)
- {
- Iterator<Map.Entry<ProtocolProviderService, List<String>>>
- iter
- = callees.entrySet().iterator();
- Map.Entry<ProtocolProviderService, List<String>>
- entry
- = iter.next();
- ProtocolProviderService pps = entry.getKey();
-
- if ((pps != null)
- && ProtocolNames.JABBER.equals(
- pps.getProtocolName()))
- {
- Object jitsiVideoBridge = null;
+ CallConference conference = null;
- try
- {
- jitsiVideoBridge
- = pps
- .getClass()
- .getMethod("getJitsiVideoBridge")
- .invoke(pps);
- }
- catch (Throwable t)
- {
- if (t instanceof ThreadDeath)
- throw (ThreadDeath) t;
- else
- {
- logger.error(
- "Failed to determine whether Jitsi"
- + " VideoBridge is available for "
- + pps.getAccountID());
- }
- }
-
- if ((jitsiVideoBridge instanceof String)
- && (((String) jitsiVideoBridge).length() != 0))
- {
- conference = new MediaAwareCallConference(true);
- }
- }
- }
- }
- else
+ if (call != null)
conference = call.getConference();
for(Map.Entry<ProtocolProviderService, List<String>> entry
@@ -2156,6 +2130,76 @@ public class CallManager
}
/**
+ * Invites a list of callees to a specific conference <tt>Call</tt>. If the
+ * specified <tt>Call</tt> is <tt>null</tt>, creates a brand new telephony
+ * conference.
+ */
+ private static class InviteToConferenceBridgeThread
+ extends Thread
+ {
+ private final ProtocolProviderService callProvider;
+
+ private final String[] callees;
+
+ private final Call call;
+
+ public InviteToConferenceBridgeThread(
+ ProtocolProviderService callProvider,
+ String[] callees,
+ Call call)
+ {
+ this.callProvider = callProvider;
+ this.callees = callees;
+ this.call = call;
+ }
+
+ @Override
+ public void run()
+ {
+ OperationSetVideoBridge opSetVideoBridge
+ = callProvider.getOperationSet(
+ OperationSetVideoBridge.class);
+
+ // Normally if this method is called then this should not happen
+ // but we check in order to be sure to be able to proceed.
+ if (opSetVideoBridge == null || !opSetVideoBridge.isActive())
+ return;
+
+ if (ConfigurationManager.isNormalizePhoneNumber())
+ normalizePhoneNumbers(callees);
+
+ try
+ {
+ if (call == null)
+ {
+ opSetVideoBridge.createConfCall(callees);
+ }
+ else
+ {
+ for (String contact : callees)
+ {
+ opSetVideoBridge.inviteCalleeToCall(contact, call);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ logger.error(
+ "Failed to invite callees: "
+ + Arrays.toString(callees),
+ e);
+ new ErrorDialog(
+ null,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR"),
+ e.getMessage(),
+ ErrorDialog.ERROR)
+ .showDialog();
+ }
+ }
+ }
+
+ /**
* Hangs up a specific <tt>Call</tt> (i.e. all <tt>CallPeer</tt>s associated
* with a <tt>Call</tt>), <tt>CallConference</tt> (i.e. all <tt>Call</tt>s
* participating in a <tt>CallConference</tt>), or <tt>CallPeer</tt>.
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 901b048..b95aa37 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
@@ -391,7 +391,17 @@ public class CallPanel
}
else if (buttonName.equals(CONFERENCE_BUTTON))
{
- new ConferenceInviteDialog(callConference).setVisible(true);
+ ConferenceInviteDialog inviteDialog;
+ if (callConference.isJitsiVideoBridge())
+ inviteDialog = new ConferenceInviteDialog(
+ callConference,
+ callConference.getCalls()
+ .get(0).getProtocolProvider(),
+ true);
+ else
+ inviteDialog = new ConferenceInviteDialog(callConference);
+
+ inviteDialog.setVisible(true);
}
else if (buttonName.equals(CHAT_BUTTON))
{
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
index edf6dde..9ddf99d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
@@ -65,32 +65,36 @@ public class ConferenceInviteDialog
private ContactSourceService currentStringContactSource;
/**
+ * The previously selected protocol provider, with which this dialog has
+ * been instantiated.
+ */
+ private ProtocolProviderService preselectedProtocolProvider;
+
+ /**
* Initializes a new <tt>ConferenceInviteDialog</tt> instance which is to
* invite contacts/participants in a specific telephony conference.
*
* @param conference the telephony conference in which the new instance is
* to invite contacts/participants
*/
- public ConferenceInviteDialog(CallConference conference)
+ public ConferenceInviteDialog( CallConference conference,
+ ProtocolProviderService preselectedProvider,
+ final boolean isVideoBridge)
{
- super(GuiActivator.getResources()
- .getI18NString("service.gui.INVITE_CONTACT_TO_CALL"), false);
+ // Set the correct dialog title depending if we're going to create a
+ // video bridge conference call
+ super((isVideoBridge
+ ? GuiActivator.getResources()
+ .getI18NString("service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE")
+ : GuiActivator.getResources()
+ .getI18NString("service.gui.INVITE_CONTACT_TO_CALL")),
+ false);
this.conference = conference;
+ this.preselectedProtocolProvider = preselectedProvider;
- JLabel accountSelectorLabel = new JLabel(
- GuiActivator.getResources().getI18NString("service.gui.CALL_VIA"));
-
- TransparentPanel accountSelectorPanel
- = new TransparentPanel(new BorderLayout());
-
- accountSelectorPanel.setBorder(
- BorderFactory.createEmptyBorder(5, 5, 5, 5));
- accountSelectorPanel.add(accountSelectorLabel, BorderLayout.WEST);
- accountSelectorPanel.add(accountSelectorBox, BorderLayout.CENTER);
-
- // Initialize the account selector box.
- this.initAccountListData();
+ if (preselectedProtocolProvider == null)
+ initAccountSelectorPanel();
// init the list, as we check whether features are supported
// it may take some time if we have too much contacts
@@ -101,13 +105,114 @@ public class ConferenceInviteDialog
initContactSources();
// Initialize the list of contacts to select from.
- initContactListData(
- (ProtocolProviderService) accountSelectorBox
- .getSelectedItem());
+ if (preselectedProtocolProvider != null)
+ initContactListData(preselectedProtocolProvider);
+ else
+ initContactListData(
+ (ProtocolProviderService) accountSelectorBox
+ .getSelectedItem());
}
});
- this.getContentPane().add(accountSelectorPanel, BorderLayout.NORTH);
+ this.addInviteButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ Collection<UIContact> selectedContacts
+ = destContactList.getContacts(null);
+
+ if (selectedContacts != null && selectedContacts.size() > 0)
+ {
+ if (preselectedProtocolProvider == null)
+ preselectedProtocolProvider
+ = (ProtocolProviderService) accountSelectorBox
+ .getSelectedItem();
+
+ if (isVideoBridge)
+ inviteVideoBridgeContacts( preselectedProtocolProvider,
+ selectedContacts);
+ else
+ inviteContacts(selectedContacts);
+
+ // Store the last used account in order to pre-select it
+ // next time.
+ ConfigurationManager.setLastCallConferenceProvider(
+ preselectedProtocolProvider);
+
+ dispose();
+ }
+ else
+ {
+ // TODO: The underlying invite dialog should show a message
+ // to the user that she should select at least two contacts
+ // in order to create a conference.
+ }
+ }
+ });
+
+ this.addCancelButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ dispose();
+ }
+ });
+ }
+
+ /**
+ * Constructs the <tt>ConferenceInviteDialog</tt>.
+ */
+ public ConferenceInviteDialog()
+ {
+ this(null, null, false);
+ }
+
+ /**
+ * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying an
+ * already created conference. To use when inviting contacts to an existing
+ * conference is needed.
+ *
+ * @param conference the existing <tt>CallConference</tt>
+ */
+ public ConferenceInviteDialog(CallConference conference)
+ {
+ this(conference, null, false);
+ }
+
+ /**
+ * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying a
+ * preselected protocol provider to be used and if this is an invite for
+ * a video bridge conference.
+ *
+ * @param selectedConfProvider the preselected protocol provider
+ * @param isVideoBridge indicates if this dialog should create a conference
+ * through a video bridge
+ */
+ public ConferenceInviteDialog(
+ ProtocolProviderService selectedConfProvider,
+ boolean isVideoBridge)
+ {
+ this(null, selectedConfProvider, isVideoBridge);
+ }
+
+ /**
+ * Initializes the account selector panel.
+ */
+ private void initAccountSelectorPanel()
+ {
+ JLabel accountSelectorLabel = new JLabel(
+ GuiActivator.getResources().getI18NString("service.gui.CALL_VIA"));
+
+ TransparentPanel accountSelectorPanel
+ = new TransparentPanel(new BorderLayout());
+
+ accountSelectorPanel.setBorder(
+ BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ accountSelectorPanel.add(accountSelectorLabel, BorderLayout.WEST);
+ accountSelectorPanel.add(accountSelectorBox, BorderLayout.CENTER);
+
+ // Initialize the account selector box.
+ this.initAccountListData();
this.accountSelectorBox.setRenderer(new DefaultListCellRenderer()
{
@@ -152,52 +257,7 @@ public class ConferenceInviteDialog
}
});
- this.addInviteButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- Collection<UIContact> selectedContacts
- = destContactList.getContacts(null);
-
- if (selectedContacts != null && selectedContacts.size() > 0)
- {
- ProtocolProviderService selectedProvider
- = (ProtocolProviderService) accountSelectorBox
- .getSelectedItem();
-
- inviteContacts(selectedContacts);
-
- // Store the last used account in order to pre-select it
- // next time.
- ConfigurationManager.setLastCallConferenceProvider(
- selectedProvider);
-
- dispose();
- }
- else
- {
- // TODO: The underlying invite dialog should show a message
- // to the user that she should select at least two contacts
- // in order to create a conference.
- }
- }
- });
-
- this.addCancelButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- dispose();
- }
- });
- }
-
- /**
- * Constructs the <tt>ConferenceInviteDialog</tt>.
- */
- public ConferenceInviteDialog()
- {
- this(null);
+ this.getContentPane().add(accountSelectorPanel, BorderLayout.NORTH);
}
/**
@@ -389,4 +449,49 @@ public class ConferenceInviteDialog
CallManager.createConferenceCall(selectedProviderCallees);
}
}
+
+ /**
+ * Invites the contacts to the chat conference.
+ *
+ * @param contacts the list of contacts to invite
+ */
+ private void inviteVideoBridgeContacts(
+ ProtocolProviderService preselectedProvider,
+ Collection<UIContact> contacts)
+ {
+ List<String> callees = new ArrayList<String>();
+
+ Iterator<UIContact> contactsIter = contacts.iterator();
+
+ while (contactsIter.hasNext())
+ {
+ UIContact uiContact = contactsIter.next();
+
+ Iterator<UIContactDetail> contactDetailsIter = uiContact
+ .getContactDetailsForOperationSet(
+ OperationSetBasicTelephony.class).iterator();
+
+ // We invite the first protocol contact that corresponds to the
+ // invite provider.
+ if (contactDetailsIter.hasNext())
+ {
+ UIContactDetail inviteDetail = contactDetailsIter.next();
+
+ callees.add(inviteDetail.getAddress());
+ }
+ }
+
+ if(conference != null)
+ {
+ CallManager.inviteToVideoBridgeConfCall(
+ callees.toArray(new String[callees.size()]),
+ conference.getCalls().get(0));
+ }
+ else
+ {
+ CallManager.createVideoBridgeConfCall(
+ preselectedProvider,
+ callees.toArray(new String[callees.size()]));
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/ToolsMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/ToolsMenu.java
index 7a71ebf..fa44b06 100644
--- a/src/net/java/sip/communicator/impl/gui/main/menus/ToolsMenu.java
+++ b/src/net/java/sip/communicator/impl/gui/main/menus/ToolsMenu.java
@@ -8,8 +8,11 @@ package net.java.sip.communicator.impl.gui.main.menus;
import java.awt.*;
import java.awt.event.*;
+import java.util.*;
+import java.util.List;
import javax.swing.*;
+import javax.swing.event.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.event.*;
@@ -41,6 +44,7 @@ public class ToolsMenu
extends SIPCommMenu
implements ActionListener,
PluginComponentListener,
+ ServiceListener,
Skinnable
{
/**
@@ -59,11 +63,16 @@ public class ToolsMenu
private static final String AUTO_ANSWER_MENU_DISABLED_PROP =
"net.java.sip.communicator.impl.gui.main.menus.AUTO_ANSWER_MENU_DISABLED";
- /**
+ /**
* Conference call menu item.
*/
private JMenuItem conferenceMenuItem;
+ /**
+ * Video bridge conference call menu. In the case of more than one account.
+ */
+ private JMenuItem videoBridgeMenuItem;
+
/**
* Show/Hide offline contacts menu item.
*/
@@ -210,7 +219,6 @@ public class ToolsMenu
soundHandler.setMute(!soundHandler.isMute());
}
}
-
}
String itemTextKey = !isMute
@@ -296,8 +304,6 @@ public class ToolsMenu
}
}
- // Marks this feature as an ongoing work until its completed and fully
- // tested.
conferenceMenuItem = new JMenuItem(
GuiActivator.getResources().getI18NString(
"service.gui.CREATE_CONFERENCE_CALL"));
@@ -308,6 +314,8 @@ public class ToolsMenu
conferenceMenuItem.addActionListener(this);
this.add(conferenceMenuItem);
+ initVideoBridgeMenu();
+
if(!GuiActivator.getConfigurationService().getBoolean(
AUTO_ANSWER_MENU_DISABLED_PROP,
false))
@@ -359,6 +367,114 @@ public class ToolsMenu
}
/**
+ * Returns a list of all available video bridge providers.
+ *
+ * @return a list of all available video bridge providers
+ */
+ private List<ProtocolProviderService> getVideoBridgeProviders()
+ {
+ List<ProtocolProviderService> activeBridgeProviders
+ = new ArrayList<ProtocolProviderService>();
+
+ for (ProtocolProviderService videoBridgeProvider
+ : GuiActivator.getRegisteredProviders(
+ OperationSetVideoBridge.class))
+ {
+ OperationSetVideoBridge videoBridgeOpSet
+ = videoBridgeProvider.getOperationSet(
+ OperationSetVideoBridge.class);
+
+ // Check if the video bridge is actually active before adding it to
+ // the list of active providers.
+ if (videoBridgeOpSet.isActive())
+ activeBridgeProviders.add(videoBridgeProvider);
+ }
+
+ return activeBridgeProviders;
+ }
+
+ /**
+ * Initializes the appropriate video bridge menu depending on how many
+ * registered providers do we have that support the
+ * <tt>OperationSetVideoBridge</tt>.
+ */
+ private void initVideoBridgeMenu()
+ {
+ // If already created remove the previous menu in order to reinitialize
+ // it.
+ if (videoBridgeMenuItem != null)
+ {
+ remove(videoBridgeMenuItem);
+ videoBridgeMenuItem = null;
+ }
+ else
+ {
+ // For now we re-init the video bridge menu item each time the
+ // parent menu is selected in order to be able to refresh the list
+ // of available video bridge active providers.
+ addMenuListener(new MenuListener()
+ {
+ public void menuSelected(MenuEvent arg0)
+ {
+ initVideoBridgeMenu();
+ }
+
+ public void menuDeselected(MenuEvent arg0) {}
+
+ public void menuCanceled(MenuEvent arg0) {}
+ });
+ }
+
+ List<ProtocolProviderService> videoBridgeProviders
+ = getVideoBridgeProviders();
+
+ // Add a service listener in order to be notified when a new protocol
+ // privder is added or removed and the list should be refreshed.
+ GuiActivator.bundleContext.addServiceListener(this);
+
+ if (videoBridgeProviders == null || videoBridgeProviders.size() <= 0)
+ {
+ videoBridgeMenuItem = new VideoBridgeProviderMenuItem(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_VIDEO_BRIDGE"), null);
+ videoBridgeMenuItem.setEnabled(false);
+ }
+ else if (videoBridgeProviders.size() == 1)
+ {
+ videoBridgeMenuItem = new VideoBridgeProviderMenuItem(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_VIDEO_BRIDGE"),
+ videoBridgeProviders.get(0));
+ videoBridgeMenuItem.setName("videoBridge");
+ videoBridgeMenuItem.addActionListener(this);
+ }
+ else if (videoBridgeProviders.size() > 1)
+ {
+ videoBridgeMenuItem = new SIPCommMenu(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_VIDEO_BRIDGE_MENU"));
+
+ for (ProtocolProviderService videoBridgeProvider
+ : videoBridgeProviders)
+ {
+ VideoBridgeProviderMenuItem videoBridgeItem
+ = new VideoBridgeProviderMenuItem(videoBridgeProvider);
+
+ ((JMenu) videoBridgeMenuItem).add(videoBridgeItem);
+ videoBridgeItem.setIcon(
+ ImageLoader.getAccountStatusImage(videoBridgeProvider));
+ }
+ }
+
+ videoBridgeMenuItem.setIcon(GuiActivator.getResources().getImage(
+ "service.gui.icons.VIDEO_BRIDGE"));
+ videoBridgeMenuItem.setMnemonic(GuiActivator.getResources()
+ .getI18nMnemonic("service.gui.CREATE_VIDEO_BRIDGE"));
+
+ insert(videoBridgeMenuItem, 1);
+ }
+
+ /**
* Registers the preferences item in the MacOS X menu.
* @return <tt>true</tt> if the operation succeeds, otherwise - returns
* <tt>false</tt>
@@ -391,7 +507,9 @@ public class ToolsMenu
public void loadSkin()
{
conferenceMenuItem.setIcon(GuiActivator.getResources().getImage(
- "service.gui.icons.CHAT_ROOM_16x16_ICON"));
+ "service.gui.icons.CONFERENCE_CALL"));
+ videoBridgeMenuItem.setIcon(GuiActivator.getResources().getImage(
+ "service.gui.icons.VIDEO_BRIDGE"));
hideOfflineMenuItem.setIcon(GuiActivator.getResources().getImage(
"service.gui.icons.SHOW_HIDE_OFFLINE_ICON"));
soundMenuItem.setIcon(GuiActivator.getResources().getImage(
@@ -403,4 +521,94 @@ public class ToolsMenu
"service.gui.icons.CONFIGURE_ICON"));
}
}
+
+ /**
+ * The <tt>VideoBridgeProviderMenuItem</tt> for each protocol provider.
+ */
+ private class VideoBridgeProviderMenuItem
+ extends JMenuItem
+ implements ActionListener
+ {
+ private ProtocolProviderService protocolProvider;
+
+ /**
+ * Creates an instance of <tt>VideoBridgeProviderMenuItem</tt> by
+ * specifying the corresponding <tt>ProtocolProviderService</tt> that
+ * provides the video bridge.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt> that
+ * provides the video bridge
+ */
+ public VideoBridgeProviderMenuItem(
+ ProtocolProviderService protocolProvider)
+ {
+ this (null, protocolProvider);
+ }
+
+ /**
+ * Creates an instance of <tt>VideoBridgeProviderMenuItem</tt> by
+ * specifying the corresponding <tt>ProtocolProviderService</tt> that
+ * provides the video bridge.
+ *
+ * @param name the name of the menu item
+ * @param protocolProvider the <tt>ProtocolProviderService</tt> that
+ * provides the video bridge
+ */
+ public VideoBridgeProviderMenuItem(
+ String name,
+ ProtocolProviderService protocolProvider)
+ {
+ if (name != null && name.length() > 0)
+ setText(name);
+ else
+ setText(protocolProvider.getAccountID().getDisplayName());
+
+ this.protocolProvider = protocolProvider;
+
+ addActionListener(this);
+ }
+
+ /**
+ * Opens a conference invite dialog when this menu is selected.
+ */
+ public void actionPerformed(ActionEvent arg0)
+ {
+ new ConferenceInviteDialog(protocolProvider, true).setVisible(true);
+ }
+ }
+
+ /**
+ * Implements the <tt>ServiceListener</tt> method. Verifies whether the
+ * passed event concerns a <tt>ProtocolProviderService</tt> and adds the
+ * corresponding UI controls in the menu.
+ *
+ * @param event The <tt>ServiceEvent</tt> object.
+ */
+ public void serviceChanged(ServiceEvent event)
+ {
+ ServiceReference serviceRef = event.getServiceReference();
+
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know
+ if (serviceRef.getBundle().getState() == Bundle.STOPPING)
+ {
+ return;
+ }
+
+ Object service = GuiActivator.bundleContext.getService(serviceRef);
+
+ // we don't care if the source service is not a protocol provider
+ if (!(service instanceof ProtocolProviderService))
+ {
+ return;
+ }
+
+ switch (event.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ case ServiceEvent.UNREGISTERING:
+ initVideoBridgeMenu();
+ break;
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java
new file mode 100644
index 0000000..2408cd7
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java
@@ -0,0 +1,106 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import java.util.*;
+
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smackx.packet.*;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.cobri.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.media.*;
+
+/**
+ * Implements <tt>OperationSetVideoBridge</tt> for Jabber.
+ *
+ * @author Yana Stamcheva
+ */
+public class OperationSetVideoBridgeImpl
+ implements OperationSetVideoBridge
+{
+ /**
+ * The parent protocol provider.
+ */
+ private final ProtocolProviderServiceJabberImpl protocolProvider;
+
+ /**
+ * Creates an instance of <tt>OperationSetVideoBridgeImpl</tt> by
+ * specifying the parent <tt>ProtocolProviderService</tt> announcing this
+ * operation set.
+ *
+ * @param protocolProvider the parent Jabber protocol provider
+ */
+ public OperationSetVideoBridgeImpl(ProtocolProviderServiceJabberImpl
+ protocolProvider)
+ {
+ this.protocolProvider = protocolProvider;
+ }
+
+ /**
+ * Creates a conference call with the specified callees as call peers via a
+ * video bridge provided by the parent Jabber provider.
+ *
+ * @param callees the list of addresses that we should call
+ * @return the newly created conference call containing all CallPeers
+ * @throws OperationFailedException if establishing the conference call
+ * fails
+ * @throws OperationNotSupportedException if the provider does not have any
+ * conferencing features.
+ */
+ public Call createConfCall(String[] callees)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ return protocolProvider
+ .getOperationSet(OperationSetTelephonyConferencing.class)
+ .createConfCall(callees,
+ new MediaAwareCallConference(true));
+ }
+
+ /**
+ * Invites the callee represented by the specified uri to an already
+ * existing call using a video bridge provided by the parent Jabber provider.
+ * The difference between this method and createConfCall is that
+ * inviteCalleeToCall allows a user to add new peers to an already
+ * established conference.
+ *
+ * @param uri the callee to invite to an existing conf call.
+ * @param call the call that we should invite the callee to.
+ * @return the CallPeer object corresponding to the callee represented by
+ * the specified uri.
+ * @throws OperationFailedException if inviting the specified callee to the
+ * specified call fails
+ * @throws OperationNotSupportedException if allowing additional callees to
+ * a pre-established call is not supported.
+ */
+ public CallPeer inviteCalleeToCall(String uri, Call call)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ return protocolProvider.getOperationSet(
+ OperationSetTelephonyConferencing.class).inviteCalleeToCall(
+ uri,
+ call);
+ }
+
+ /**
+ * Indicates if there's an active video bridge available at this moment. The
+ * Jabber provider may announce support for video bridge, but it should not
+ * be used for calling until it becomes actually active.
+ *
+ * @return <tt>true</tt> to indicate that there's currently an active
+ * available video bridge, <tt>false</tt> - otherwise
+ */
+ public boolean isActive()
+ {
+ String jitsiVideoBridge = protocolProvider.getJitsiVideoBridge();
+
+ return (jitsiVideoBridge != null
+ && jitsiVideoBridge.length() > 0);
+ }
+}
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 f2a021c..6ac39f0 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -1728,6 +1728,10 @@ public class ProtocolProviderServiceJabberImpl
OperationSetBasicAutoAnswer.class,
new OperationSetAutoAnswerJabberImpl(this));
+ addSupportedOperationSet(
+ OperationSetVideoBridge.class,
+ new OperationSetVideoBridgeImpl(this));
+
// init DTMF
OperationSetDTMFJabberImpl operationSetDTMFSip
= new OperationSetDTMFJabberImpl(this);
@@ -1795,7 +1799,7 @@ public class ProtocolProviderServiceJabberImpl
supportedFeatures.add(MessageCorrectionExtension.NAMESPACE);
addSupportedOperationSet(OperationSetMessageCorrection.class,
basicInstantMessaging);
-
+
OperationSetChangePassword opsetChangePassword
= new OperationSetChangePasswordJabberImpl(this);
addSupportedOperationSet(OperationSetChangePassword.class,
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetVideoBridge.java b/src/net/java/sip/communicator/service/protocol/OperationSetVideoBridge.java
new file mode 100644
index 0000000..caafb1b
--- /dev/null
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetVideoBridge.java
@@ -0,0 +1,62 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.protocol;
+
+/**
+ * Provides operations necessary to create and handle conferencing calls through
+ * a video bridge.
+ *
+ * @author Yana Stamcheva
+ */
+public interface OperationSetVideoBridge
+ extends OperationSet
+{
+ /**
+ * Creates a conference call with the specified callees as call peers via a
+ * video bridge provided by the parent Jabber provider.
+ *
+ * @param callees the list of addresses that we should call
+ * @return the newly created conference call containing all CallPeers
+ * @throws OperationFailedException if establishing the conference call
+ * fails
+ * @throws OperationNotSupportedException if the provider does not have any
+ * conferencing features.
+ */
+ public Call createConfCall(String[] callees)
+ throws OperationFailedException,
+ OperationNotSupportedException;
+
+ /**
+ * Invites the callee represented by the specified uri to an already
+ * existing call. The difference between this method and createConfCall is
+ * that inviteCalleeToCall allows a user to transform an existing 1-to-1
+ * call into a conference call, or add new peers to an already established
+ * conference.
+ *
+ * @param uri the callee to invite to an existing conf call.
+ * @param call the call that we should invite the callee to.
+ * @return the CallPeer object corresponding to the callee represented by
+ * the specified uri.
+ * @throws OperationFailedException if inviting the specified callee to the
+ * specified call fails
+ * @throws OperationNotSupportedException if allowing additional callees to
+ * a pre-established call is not supported.
+ */
+ public CallPeer inviteCalleeToCall(String uri, Call call)
+ throws OperationFailedException,
+ OperationNotSupportedException;
+
+ /**
+ * Indicates if there's an active video bridge available at this moment. The
+ * Jabber provider may announce support for video bridge, but it should not
+ * be used for calling until it becomes actually active.
+ *
+ * @return <tt>true</tt> to indicate that there's currently an active
+ * available video bridge, <tt>false</tt> - otherwise
+ */
+ public boolean isActive();
+}