diff options
author | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2012-02-13 21:04:27 +0000 |
---|---|---|
committer | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2012-02-13 21:04:27 +0000 |
commit | f8639bd321f2c3ca0c76c2d8c4b90ae06e895a89 (patch) | |
tree | e276cc64ac6eeb288f561f706c98c9c1eb7b6ee0 /src/net/java | |
parent | 03665dbd8b476236fd842ee37dfb6050d61fadd3 (diff) | |
download | jitsi-f8639bd321f2c3ca0c76c2d8c4b90ae06e895a89.zip jitsi-f8639bd321f2c3ca0c76c2d8c4b90ae06e895a89.tar.gz jitsi-f8639bd321f2c3ca0c76c2d8c4b90ae06e895a89.tar.bz2 |
Commits work in progress on fixing leaks of CallDialog.
Diffstat (limited to 'src/net/java')
14 files changed, 662 insertions, 536 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java index 2dc8416..36f31d1 100644 --- a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java @@ -58,32 +58,28 @@ public class GeneralDialPadDialog */ public GeneralDialPadDialog() { - if (OSUtils.IS_MAC) - { - HudWindow window = new HudWindow(); - - dialPadDialog = window.getJDialog(); - } - else - { - dialPadDialog = new SIPCommDialog(false); - } - - callField = new CallField(GuiActivator.getResources() - .getI18NString("service.gui.ENTER_NAME_OR_NUMBER")); - + dialPadDialog + = OSUtils.IS_MAC + ? new HudWindow().getJDialog() + : new SIPCommDialog(false); dialPadDialog.setTitle( - GuiActivator.getResources().getI18NString("service.gui.DIALPAD")); + GuiActivator.getResources().getI18NString( + "service.gui.DIALPAD")); + + callField + = new CallField( + GuiActivator.getResources().getI18NString( + "service.gui.ENTER_NAME_OR_NUMBER")); initInputMap(); JPanel mainPanel = new TransparentPanel(new BorderLayout()); mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - mainPanel.add(callField, BorderLayout.NORTH); - DTMFHandler dtmfHandler = new DTMFHandler(); - dtmfHandler.addParent(dialPadDialog); + + final DTMFHandler dtmfHandler = new DTMFHandler(); + mainPanel.add(new GeneralDialPanel(this, dtmfHandler)); mainPanel.add(createCallPanel(), BorderLayout.SOUTH); @@ -92,28 +88,37 @@ public class GeneralDialPadDialog dialPadDialog.addWindowListener(new WindowAdapter() { + @Override public void windowOpened(WindowEvent e) { if (keyManager == null) { keyManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - - keyDispatcher = new MainKeyDispatcher(keyManager); } + if (keyDispatcher == null) + keyDispatcher = new MainKeyDispatcher(keyManager); + keyManager.addKeyEventDispatcher(keyDispatcher); - keyManager.addKeyEventDispatcher( - new MainKeyDispatcher(keyManager)); + dtmfHandler.addParent(dialPadDialog); } @Override public void windowClosed(WindowEvent e) { - if (keyManager != null) - keyManager.removeKeyEventDispatcher(keyDispatcher); - - keyManager = null; - keyDispatcher = null; + try + { + if (keyManager != null) + { + keyManager.removeKeyEventDispatcher(keyDispatcher); + keyManager = null; + } + keyDispatcher = null; + } + finally + { + dtmfHandler.removeParent(dialPadDialog); + } } }); } @@ -129,6 +134,7 @@ public class GeneralDialPadDialog imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape"); ActionMap amap = dialPadDialog.getRootPane().getActionMap(); + amap.put("escape", new AbstractAction() { public void actionPerformed(ActionEvent e) @@ -253,7 +259,7 @@ public class GeneralDialPadDialog */ private class MainKeyDispatcher implements KeyEventDispatcher { - private KeyboardFocusManager keyManager; + private final KeyboardFocusManager keyManager; /** * Creates an instance of <tt>MainKeyDispatcher</tt>. @@ -275,22 +281,22 @@ public class GeneralDialPadDialog { // If this window is not the focus window or if the event is not // of type PRESSED we have nothing more to do here. - if (!dialPadDialog.isFocused() - || (e.getID() != KeyEvent.KEY_TYPED)) + if (!dialPadDialog.isFocused() || (e.getID() != KeyEvent.KEY_TYPED)) return false; - if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED - || e.getKeyCode() == KeyEvent.VK_ENTER - || e.getKeyCode() == KeyEvent.VK_DELETE - || e.getKeyCode() == KeyEvent.VK_BACK_SPACE - || e.getKeyCode() == KeyEvent.VK_TAB - || e.getKeyCode() == KeyEvent.VK_SPACE) + switch (e.getKeyChar()) { + case KeyEvent.CHAR_UNDEFINED: + case KeyEvent.VK_ENTER: + case KeyEvent.VK_DELETE: + case KeyEvent.VK_BACK_SPACE: + case KeyEvent.VK_TAB: + case KeyEvent.VK_SPACE: return false; } if (!callField.isFocusOwner() - && keyManager.getFocusOwner() != null) + && (keyManager.getFocusOwner() != null)) { // Request the focus in the call field if a letter is typed. callField.requestFocusInWindow(); @@ -320,6 +326,8 @@ public class GeneralDialPadDialog /** * Creates an instance of the <tt>CallField</tt>. + * + * @param text */ public CallField(String text) { diff --git a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java index 197048f..1f61649 100755 --- a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java @@ -218,8 +218,8 @@ public class GeneralDialPanel dialPadPanel.removeAll(); Image bgImage = ImageLoader.getImage(ImageLoader.DIAL_BUTTON_BG); + DTMFHandler.DTMFToneInfo[] availableTones = DTMFHandler.AVAILABLE_TONES; - DTMFHandler.DTMFToneInfo[] availableTones = DTMFHandler.availableTones; for (int i = 0; i < availableTones.length; i++) { DTMFHandler.DTMFToneInfo info = availableTones[i]; @@ -228,15 +228,16 @@ public class GeneralDialPanel if(info.imageID == null) continue; - JComponent c; - if (OSUtils.IS_MAC) - c = createMacOSXDialButton( - info.macImageID, - info.macImageRolloverID, - info.tone.getValue()); - else - c = createDialButton( - bgImage, info.imageID, info.tone.getValue()); + JComponent c + = OSUtils.IS_MAC + ? createMacOSXDialButton( + info.macImageID, + info.macImageRolloverID, + info.tone.getValue()) + : createDialButton( + bgImage, + info.imageID, + info.tone.getValue()); dialPadPanel.add(c); } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java b/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java index 2decf88..62594fb 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java @@ -9,6 +9,7 @@ package net.java.sip.communicator.impl.gui.main.call; import java.awt.*; import java.awt.event.*; import java.util.*; +import java.util.List; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; @@ -22,247 +23,322 @@ import net.java.sip.communicator.util.*; * Handles DTMF sending and playing sound notifications for that. * * @author Damian Minkov + * @author Lyubomir Marinov */ public class DTMFHandler implements KeyEventDispatcher { /** - * Our class logger + * The <tt>Logger</tt> used by the <tt>DTMFHandler</tt> class and its + * instances for logging output. */ - private final Logger logger = Logger.getLogger(DTMFHandler.class); + private static final Logger logger = Logger.getLogger(DTMFHandler.class); /** * The call dialog, where this handler is registered. */ - private CallPanel callContainer; + private final CallPanel callContainer; /** - * Parent windows we listen key entering on them. + * The <tt>KeyboadFocusManager</tt> to which this instance is added as a + * <tt>KeyEventDispatcher</tt>. */ - ArrayList<Window> parents = new ArrayList<Window>(); + private KeyboardFocusManager keyboardFocusManager; + + /** + * The <tt>Window</tt>s which this instance listens to for key presses and + * releases. + */ + private final List<Window> parents = new ArrayList<Window>(); /** * If we are currently playing an audio for a DTMF tone. Used * to play in Loop and stop it if forced to do or new tone has come. */ - private SCAudioClip currentlyPlayingAudio = null; + private SCAudioClip currentlyPlayingAudio; /** * All available tones and its properties like images for buttons, and * sounds to be played during send. */ - public static final DTMFToneInfo[] availableTones = new DTMFToneInfo[] + public static final DTMFToneInfo[] AVAILABLE_TONES + = new DTMFToneInfo[] + { + new DTMFToneInfo( + DTMFTone.DTMF_1, + KeyEvent.VK_1, + '1', + ImageLoader.ONE_DIAL_BUTTON, + ImageLoader.ONE_DIAL_BUTTON_MAC, + ImageLoader.ONE_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_ONE), + new DTMFToneInfo( + DTMFTone.DTMF_2, + KeyEvent.VK_2, + '2', + ImageLoader.TWO_DIAL_BUTTON, + ImageLoader.TWO_DIAL_BUTTON_MAC, + ImageLoader.TWO_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_TWO), + new DTMFToneInfo( + DTMFTone.DTMF_3, + KeyEvent.VK_3, + '3', + ImageLoader.THREE_DIAL_BUTTON, + ImageLoader.THREE_DIAL_BUTTON_MAC, + ImageLoader.THREE_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_THREE), + new DTMFToneInfo( + DTMFTone.DTMF_4, + KeyEvent.VK_4, + '4', + ImageLoader.FOUR_DIAL_BUTTON, + ImageLoader.FOUR_DIAL_BUTTON_MAC, + ImageLoader.FOUR_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_FOUR), + new DTMFToneInfo( + DTMFTone.DTMF_5, + KeyEvent.VK_5, + '5', + ImageLoader.FIVE_DIAL_BUTTON, + ImageLoader.FIVE_DIAL_BUTTON_MAC, + ImageLoader.FIVE_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_FIVE), + new DTMFToneInfo( + DTMFTone.DTMF_6, + KeyEvent.VK_6, + '6', + ImageLoader.SIX_DIAL_BUTTON, + ImageLoader.SIX_DIAL_BUTTON_MAC, + ImageLoader.SIX_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_SIX), + new DTMFToneInfo( + DTMFTone.DTMF_7, + KeyEvent.VK_7, + '7', + ImageLoader.SEVEN_DIAL_BUTTON, + ImageLoader.SEVEN_DIAL_BUTTON_MAC, + ImageLoader.SEVEN_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_SEVEN), + new DTMFToneInfo( + DTMFTone.DTMF_8, + KeyEvent.VK_8, + '8', + ImageLoader.EIGHT_DIAL_BUTTON, + ImageLoader.EIGHT_DIAL_BUTTON_MAC, + ImageLoader.EIGHT_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_EIGHT), + new DTMFToneInfo( + DTMFTone.DTMF_9, + KeyEvent.VK_9, + '9', + ImageLoader.NINE_DIAL_BUTTON, + ImageLoader.NINE_DIAL_BUTTON_MAC, + ImageLoader.NINE_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_NINE), + new DTMFToneInfo( + DTMFTone.DTMF_A, + KeyEvent.VK_A, + 'a', + null, + null, + null, + null), + new DTMFToneInfo( + DTMFTone.DTMF_B, + KeyEvent.VK_B, + 'b', + null, + null, + null, + null), + new DTMFToneInfo( + DTMFTone.DTMF_C, + KeyEvent.VK_C, + 'c', + null, + null, + null, + null), + new DTMFToneInfo( + DTMFTone.DTMF_D, + KeyEvent.VK_D, + 'd', + null, + null, + null, + null), + new DTMFToneInfo( + DTMFTone.DTMF_STAR, + KeyEvent.VK_ASTERISK, + '*', + ImageLoader.STAR_DIAL_BUTTON, + ImageLoader.STAR_DIAL_BUTTON_MAC, + ImageLoader.STAR_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_STAR), + new DTMFToneInfo( + DTMFTone.DTMF_0, + KeyEvent.VK_0, + '0', + ImageLoader.ZERO_DIAL_BUTTON, + ImageLoader.ZERO_DIAL_BUTTON_MAC, + ImageLoader.ZERO_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_ZERO), + new DTMFToneInfo( + DTMFTone.DTMF_SHARP, + KeyEvent.VK_NUMBER_SIGN, + '#', + ImageLoader.DIEZ_DIAL_BUTTON, + ImageLoader.DIEZ_DIAL_BUTTON_MAC, + ImageLoader.DIEZ_DIAL_BUTTON_MAC_ROLLOVER, + SoundProperties.DIAL_DIEZ) + }; + + /** + * Creates DTMF handler for a call. + */ + public DTMFHandler() { - new DTMFToneInfo( - DTMFTone.DTMF_1, - KeyEvent.VK_1, - '1', - ImageLoader.ONE_DIAL_BUTTON, - ImageLoader.ONE_DIAL_BUTTON_MAC, - ImageLoader.ONE_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_ONE), - new DTMFToneInfo( - DTMFTone.DTMF_2, - KeyEvent.VK_2, - '2', - ImageLoader.TWO_DIAL_BUTTON, - ImageLoader.TWO_DIAL_BUTTON_MAC, - ImageLoader.TWO_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_TWO), - new DTMFToneInfo( - DTMFTone.DTMF_3, - KeyEvent.VK_3, - '3', - ImageLoader.THREE_DIAL_BUTTON, - ImageLoader.THREE_DIAL_BUTTON_MAC, - ImageLoader.THREE_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_THREE), - new DTMFToneInfo( - DTMFTone.DTMF_4, - KeyEvent.VK_4, - '4', - ImageLoader.FOUR_DIAL_BUTTON, - ImageLoader.FOUR_DIAL_BUTTON_MAC, - ImageLoader.FOUR_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_FOUR), - new DTMFToneInfo( - DTMFTone.DTMF_5, - KeyEvent.VK_5, - '5', - ImageLoader.FIVE_DIAL_BUTTON, - ImageLoader.FIVE_DIAL_BUTTON_MAC, - ImageLoader.FIVE_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_FIVE), - new DTMFToneInfo( - DTMFTone.DTMF_6, - KeyEvent.VK_6, - '6', - ImageLoader.SIX_DIAL_BUTTON, - ImageLoader.SIX_DIAL_BUTTON_MAC, - ImageLoader.SIX_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_SIX), - new DTMFToneInfo( - DTMFTone.DTMF_7, - KeyEvent.VK_7, - '7', - ImageLoader.SEVEN_DIAL_BUTTON, - ImageLoader.SEVEN_DIAL_BUTTON_MAC, - ImageLoader.SEVEN_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_SEVEN), - new DTMFToneInfo( - DTMFTone.DTMF_8, - KeyEvent.VK_8, - '8', - ImageLoader.EIGHT_DIAL_BUTTON, - ImageLoader.EIGHT_DIAL_BUTTON_MAC, - ImageLoader.EIGHT_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_EIGHT), - new DTMFToneInfo( - DTMFTone.DTMF_9, - KeyEvent.VK_9, - '9', - ImageLoader.NINE_DIAL_BUTTON, - ImageLoader.NINE_DIAL_BUTTON_MAC, - ImageLoader.NINE_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_NINE), - new DTMFToneInfo( - DTMFTone.DTMF_A, - KeyEvent.VK_A, - 'a', - null, - null, - null, - null), - new DTMFToneInfo( - DTMFTone.DTMF_B, - KeyEvent.VK_B, - 'b', - null, - null, - null, - null), - new DTMFToneInfo( - DTMFTone.DTMF_C, - KeyEvent.VK_C, - 'c', - null, - null, - null, - null), - new DTMFToneInfo( - DTMFTone.DTMF_D, - KeyEvent.VK_D, - 'd', - null, - null, - null, - null), - new DTMFToneInfo( - DTMFTone.DTMF_STAR, - KeyEvent.VK_ASTERISK, - '*', - ImageLoader.STAR_DIAL_BUTTON, - ImageLoader.STAR_DIAL_BUTTON_MAC, - ImageLoader.STAR_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_STAR), - new DTMFToneInfo( - DTMFTone.DTMF_0, - KeyEvent.VK_0, - '0', - ImageLoader.ZERO_DIAL_BUTTON, - ImageLoader.ZERO_DIAL_BUTTON_MAC, - ImageLoader.ZERO_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_ZERO), - new DTMFToneInfo( - DTMFTone.DTMF_SHARP, - KeyEvent.VK_NUMBER_SIGN, - '#', - ImageLoader.DIEZ_DIAL_BUTTON, - ImageLoader.DIEZ_DIAL_BUTTON_MAC, - ImageLoader.DIEZ_DIAL_BUTTON_MAC_ROLLOVER, - SoundProperties.DIAL_DIEZ) - }; + this(null); + } /** * Creates DTMF handler for a call. - * @param callContainer the <tt>CallContainer</tt>, where this handler is + * + * @param callContainer the <tt>CallContainer</tt> where this handler is * registered */ public DTMFHandler(CallPanel callContainer) { this.callContainer = callContainer; - if(callContainer != null) - this.addParent(callContainer.getCallWindow().getFrame()); + if (this.callContainer != null) + { + final Window parent = callContainer.getCallWindow().getFrame(); - KeyboardFocusManager keyManager - = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - keyManager.addKeyEventDispatcher(this); + if (parent != null) + { + parent.addWindowListener( + new WindowAdapter() + { + @Override + public void windowClosed(WindowEvent e) + { + removeParent(parent); + } + + @Override + public void windowOpened(WindowEvent e) + { + addParent(parent); + } + }); + if (parent.isVisible()) + addParent(parent); + } + } } /** - * Creates DTMF handler for a call. + * Adds a <tt>Window</tt> on which key presses and releases are to be + * monitored for the purposes of this <tt>DTMFHandler</tt>. + * + * @param parent the <tt>Window</tt> on which key presses and releases are + * to be monitored for the purposes of this <tt>DTMFHandler</tt> */ - public DTMFHandler() + public void addParent(Window parent) { - this(null); + synchronized (parents) + { + if (!parents.contains(parent) + && parents.add(parent) + && (keyboardFocusManager == null)) + { + keyboardFocusManager + = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + keyboardFocusManager.addKeyEventDispatcher(this); + } + } } /** - * Add parent on which we listen for key entering. - * @param w + * Removes a <tt>Window</tt> on which key presses and releases are to no + * longer be monitored for the purposes of this <tt>DTMFHandler</tt>. + * + * @param parent the <tt>Window</tt> on which key presses and releases are + * to no longer be monitored for the purposes of this <tt>DTMFHandler</tt> */ - public void addParent(Window w) + public void removeParent(Window parent) { - parents.add(w); + synchronized (parents) + { + if (parents.remove(parent) + && parents.isEmpty() + && (keyboardFocusManager != null)) + { + keyboardFocusManager.removeKeyEventDispatcher(this); + keyboardFocusManager = null; + } + } } /** - * This one dispatches key events and if they are on one of our focused - * parents. - * @param e the event. - * @return whether to continue dispatching this event, for now - * always return false, so it continues. + * Dispatches a specific <tt>KeyEvent</tt>. If one of the <tt>parents</tt> + * registered with this <tt>DTMFHandler</tt> is focused, starts or stops + * sending a respective DTMF tone. + * + * @param e the <tt>KeyEvent</tt> to be dispatched + * @return <tt>true</tt> to stop dispatching the event or <tt>false</tt> to + * continue dispatching it. <tt>DTMFHandler</tt> always returns + * <tt>false</tt> */ public boolean dispatchKeyEvent(KeyEvent e) { - if(e.getID() == KeyEvent.KEY_TYPED) + if (e.getID() == KeyEvent.KEY_TYPED) return false; - boolean singleWindowRule - = GuiActivator.getUIService().getSingleWindowContainer() == null - || callContainer.isFocusOwner(); + /* + * When the UI uses a single window and we do not have a callContainer, + * we do not seem to be able to deal with the situation. + */ + if ((GuiActivator.getUIService().getSingleWindowContainer() != null) + && ((callContainer == null) || !callContainer.isFocusOwner())) + return false; boolean dispatch = false; - for (int i = 0; i < parents.size(); i++) + + synchronized (parents) { - if(parents.get(i).isFocused() && singleWindowRule) + for (int i = 0, count = parents.size(); i < count; i++) { - dispatch = true; - break; + if (parents.get(i).isFocused()) + { + dispatch = true; + break; + } } } - // if we are not in focus skip further processing - if(!dispatch) - return false; - - for (int i = 0; i < availableTones.length; i++) + // If we are not focused, the KeyEvent was not meant for us. + if (dispatch) { - DTMFToneInfo info = availableTones[i]; - - if(info.keyChar == e.getKeyChar()) + for (int i = 0; i < AVAILABLE_TONES.length; i++) { - switch (e.getID()) + DTMFToneInfo info = AVAILABLE_TONES[i]; + + if (info.keyChar == e.getKeyChar()) { - case KeyEvent.KEY_PRESSED: - startSendingDtmfTone(info); - break; - case KeyEvent.KEY_RELEASED: - stopSendingDtmfTone(); + switch (e.getID()) + { + case KeyEvent.KEY_PRESSED: + startSendingDtmfTone(info); + break; + case KeyEvent.KEY_RELEASED: + stopSendingDtmfTone(); + break; + } break; } - return false; } } @@ -276,16 +352,18 @@ public class DTMFHandler */ public void startSendingDtmfTone(String toneValue) { - for (int i = 0; i < availableTones.length; i++) + for (int i = 0; i < AVAILABLE_TONES.length; i++) { - DTMFToneInfo info = availableTones[i]; - if(info.tone.getValue().equals(toneValue)) + DTMFToneInfo info = AVAILABLE_TONES[i]; + + if (info.tone.getValue().equals(toneValue)) { startSendingDtmfTone(info); return; } } } + /** * Sends a DTMF tone to the current DTMF operation set. * @@ -300,8 +378,7 @@ public class DTMFHandler if(currentlyPlayingAudio != null) currentlyPlayingAudio.stop(); - currentlyPlayingAudio = - audioNotifier.createAudio(info.sound); + currentlyPlayingAudio = audioNotifier.createAudio(info.sound); // some little silence, must have a non-zero or it won't loop if(currentlyPlayingAudio != null) @@ -309,21 +386,19 @@ public class DTMFHandler } if (callContainer != null) + { startSendingDtmfTone( callContainer.getCurrentCallRenderer().getCall(), info); + } else { Collection<Call> activeCalls = CallManager.getActiveCalls(); if (activeCalls != null) { - Iterator<Call> callsIter = activeCalls.iterator(); - - while (callsIter.hasNext()) - { - startSendingDtmfTone(callsIter.next(), info); - } + for (Call activeCall : activeCalls) + startSendingDtmfTone(activeCall, info); } } } @@ -344,24 +419,26 @@ public class DTMFHandler { CallPeer peer = callPeers.next(); OperationSetDTMF dtmfOpSet - = peer.getProtocolProvider() - .getOperationSet(OperationSetDTMF.class); + = peer.getProtocolProvider().getOperationSet( + OperationSetDTMF.class); if (dtmfOpSet != null) { dtmfOpSet.startSendingDTMF(peer, info.tone); CallPeerRenderer peerRenderer - = callContainer.getCurrentCallRenderer() - .getCallPeerRenderer(peer); + = callContainer + .getCurrentCallRenderer() + .getCallPeerRenderer(peer); + if (peerRenderer != null) peerRenderer.printDTMFTone(info.keyChar); } } } - catch (Throwable e1) + catch (Throwable t) { - logger.error("Failed to send a DTMF tone.", e1); + logger.error("Failed to send a DTMF tone.", t); } } @@ -370,26 +447,23 @@ public class DTMFHandler */ public synchronized void stopSendingDtmfTone() { - if(currentlyPlayingAudio != null) + if (currentlyPlayingAudio != null) currentlyPlayingAudio.stop(); - currentlyPlayingAudio = null; if (callContainer != null) + { stopSendingDtmfTone( - callContainer.getCurrentCallRenderer().getCall()); + callContainer.getCurrentCallRenderer().getCall()); + } else { Collection<Call> activeCalls = CallManager.getActiveCalls(); if (activeCalls != null) { - Iterator<Call> callsIter = activeCalls.iterator(); - - while (callsIter.hasNext()) - { - stopSendingDtmfTone(callsIter.next()); - } + for (Call activeCall : activeCalls) + stopSendingDtmfTone(activeCall); } } } @@ -409,17 +483,16 @@ public class DTMFHandler { CallPeer peer = callPeers.next(); OperationSetDTMF dtmfOpSet - = peer - .getProtocolProvider() - .getOperationSet(OperationSetDTMF.class); + = peer.getProtocolProvider().getOperationSet( + OperationSetDTMF.class); if (dtmfOpSet != null) dtmfOpSet.stopSendingDTMF(peer); } } - catch (Throwable e1) + catch (Throwable t) { - logger.error("Failed to send a DTMF tone.", e1); + logger.error("Failed to send a DTMF tone.", t); } } @@ -431,37 +504,37 @@ public class DTMFHandler /** * The tone itself */ - public DTMFTone tone; + public final DTMFTone tone; /** * The key code when entered from keyboard. */ - public int keyCode; + public final int keyCode; /** * The char associated with this DTMF tone. */ - public char keyChar; + public final char keyChar; /** * The image to display in buttons sending DTMFs. */ - public ImageID imageID; + public final ImageID imageID; /** * The image to display on Mac buttons. */ - public ImageID macImageID; + public final ImageID macImageID; /** * The id of the image to display on Mac buttons on rollover. */ - public ImageID macImageRolloverID; + public final ImageID macImageRolloverID; /** * The sound to play during send of this tone. */ - public String sound; + public final String sound; /** * Creates DTMF extended info. @@ -469,13 +542,15 @@ public class DTMFHandler * @param keyCode its key code. * @param keyChar the char associated with the DTMF * @param imageID the image if any. - * @param macImageID the Mac image if any. + * @param macImageID the Mac OS X-specific image if any. + * @param macImageRolloverID the Mac OS X-specific rollover image if any * @param sound the sound if any. */ public DTMFToneInfo( - DTMFTone tone, int keyCode, char keyChar, - ImageID imageID, ImageID macImageID, - ImageID macImageRolloverID, String sound) + DTMFTone tone, + int keyCode, char keyChar, + ImageID imageID, ImageID macImageID, ImageID macImageRolloverID, + String sound) { this.tone = tone; this.keyCode = keyCode; diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java index 56d9cf4..1e7ec82 100755 --- a/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java @@ -189,17 +189,21 @@ public class DialPanel dialPadPanel.removeAll(); Image bgImage = ImageLoader.getImage(ImageLoader.DIAL_BUTTON_BG); + DTMFHandler.DTMFToneInfo[] availableTones = DTMFHandler.AVAILABLE_TONES; - DTMFHandler.DTMFToneInfo[] availableTones = DTMFHandler.availableTones; for (int i = 0; i < availableTones.length; i++) { DTMFHandler.DTMFToneInfo info = availableTones[i]; - // we add only buttons having image - if(info.imageID == null) - continue; - dialPadPanel.add( - createDialButton(bgImage, info.imageID, info.tone.getValue())); + // we add only buttons having image + if (info.imageID != null) + { + dialPadPanel.add( + createDialButton( + bgImage, + info.imageID, + info.tone.getValue())); + } } } } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DialpadDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/DialpadDialog.java index aa68f37..bdc96e5 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/DialpadDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DialpadDialog.java @@ -17,7 +17,7 @@ import net.java.sip.communicator.impl.gui.utils.*; * The <tt>DialpadDialog</tt> is a popup dialog containing a dialpad. * * @author Yana Stamcheva - * @author Lubomir Marinov + * @author Lyubomir Marinov */ public class DialpadDialog extends JDialog @@ -34,11 +34,13 @@ public class DialpadDialog dialPanel.setOpaque(false); BackgroundPanel bgPanel = new BackgroundPanel(); + bgPanel.setLayout(new BorderLayout()); bgPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); bgPanel.add(dialPanel, BorderLayout.CENTER); Container contentPane = getContentPane(); + contentPane.setLayout(new BorderLayout()); contentPane.add(bgPanel, BorderLayout.CENTER); @@ -51,14 +53,27 @@ public class DialpadDialog * * @param dtmfHandler handles DTMFs. */ - public DialpadDialog( - DTMFHandler dtmfHandler) + public DialpadDialog(final DTMFHandler dtmfHandler) { this(new DialPanel(dtmfHandler)); this.setModal(false); - dtmfHandler.addParent(this); + addWindowListener( + new WindowAdapter() + { + @Override + public void windowClosed(WindowEvent e) + { + dtmfHandler.removeParent(DialpadDialog.this); + } + + @Override + public void windowOpened(WindowEvent e) + { + dtmfHandler.addParent(DialpadDialog.this); + } + }); } /** diff --git a/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java b/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java index 85bef47..4bab80d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java @@ -50,7 +50,7 @@ public class UIVideoHandler * Listener for all key and mouse events. It is used for desktop sharing * purposes. */ - private MouseAndKeyListener mouseAndKeyListener = null; + private MouseAndKeyListener mouseAndKeyListener; /** * The local video mouse listener. @@ -676,6 +676,7 @@ public class UIVideoHandler remoteVideo.removeMouseWheelListener(mouseAndKeyListener); } } + /** * Listener for all key and mouse events and will transfer them to * the <tt>OperationSetDesktopSharingClient</tt>. @@ -690,7 +691,7 @@ public class UIVideoHandler MouseWheelListener { /** - * Desktop sharing clien-side <tt>OperationSet</tt>. + * Desktop sharing client-side <tt>OperationSet</tt>. */ private final OperationSetDesktopSharingClient desktopSharingClient; @@ -743,26 +744,17 @@ public class UIVideoHandler /** * {@inheritDoc} */ - public void mouseClicked(MouseEvent event) - { - /* do nothing */ - } + public void mouseClicked(MouseEvent event) {} /** * {@inheritDoc} */ - public void mouseEntered(MouseEvent event) - { - /* do nothing */ - } + public void mouseEntered(MouseEvent event) {} /** * {@inheritDoc} */ - public void mouseExited(MouseEvent event) - { - /* do nothing */ - } + public void mouseExited(MouseEvent event) {} /** * {@inheritDoc} @@ -825,9 +817,7 @@ public class UIVideoHandler char key = event.getKeyChar(); if(key != '\n' && key != '\b') - { desktopSharingClient.sendKeyboardEvent(callPeer, event); - } } /** @@ -838,11 +828,8 @@ public class UIVideoHandler public void remoteControlGranted(RemoteControlGrantedEvent event) { allowRemoteControl = true; - if(remoteVideo != null) - { addMouseAndKeyListeners(); - } } /** @@ -1018,14 +1005,14 @@ public class UIVideoHandler */ public OperationSetDesktopSharingClient addRemoteControlListener() { - final Call call = callPeer.getCall(); + Call call = callPeer.getCall(); if (call == null) return null; - OperationSetDesktopSharingClient desktopSharingClient = - call.getProtocolProvider() - .getOperationSet(OperationSetDesktopSharingClient.class); + OperationSetDesktopSharingClient desktopSharingClient + = call.getProtocolProvider().getOperationSet( + OperationSetDesktopSharingClient.class); if(desktopSharingClient != null) { @@ -1036,25 +1023,27 @@ public class UIVideoHandler } /** - * Sets up listening to remote-control notifications (granted or revoked). - * - * @return reference to <tt>OperationSetDesktopSharingClient</tt> + * Removes the setup for listening to remote-control notifications (granted + * or revoked). */ public void removeRemoteControlListener() { - final Call call = callPeer.getCall(); - - if (call == null) - return; + if (mouseAndKeyListener != null) + { + Call call = callPeer.getCall(); - OperationSetDesktopSharingClient desktopSharingClient = - call.getProtocolProvider().getOperationSet( - OperationSetDesktopSharingClient.class); + if (call != null) + { + OperationSetDesktopSharingClient desktopSharingClient + = call.getProtocolProvider().getOperationSet( + OperationSetDesktopSharingClient.class); - if(desktopSharingClient != null && mouseAndKeyListener != null) - { - desktopSharingClient - .removeRemoteControlListener(mouseAndKeyListener); + if (desktopSharingClient != null) + { + desktopSharingClient.removeRemoteControlListener( + mouseAndKeyListener); + } + } } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java index 1ece139..6f0fe5a 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java @@ -528,9 +528,7 @@ public class CallPeerMediaHandlerJabberImpl for(Map.Entry<String, String> f : adv.entrySet()) { if(f.getKey().equals("imageattr")) - { supportQualityControls = true; - } } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingClientJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingClientJabberImpl.java index aca433a..61d110a 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingClientJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingClientJabberImpl.java @@ -8,15 +8,11 @@ package net.java.sip.communicator.impl.protocol.jabber; import java.awt.*; import java.awt.event.*; -import java.util.*; -import java.util.List; // disambiguation import org.jivesoftware.smack.packet.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.inputevt.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; /** * Implements all desktop sharing client-side related functions for Jabber @@ -25,29 +21,10 @@ import net.java.sip.communicator.util.*; * @author Sebastien Vincent */ public class OperationSetDesktopSharingClientJabberImpl - implements OperationSetDesktopSharingClient + extends AbstractOperationSetDesktopSharingClient + <ProtocolProviderServiceJabberImpl> { /** - * Our class logger. - */ - private static final Logger logger = - Logger.getLogger(OperationSetDesktopSharingClientJabberImpl.class); - - /** - * The Jabber <tt>ProtocolProviderService</tt> implementation which created - * this instance and for which telephony conferencing services are being - * provided by this instance. - */ - private final ProtocolProviderServiceJabberImpl parentProvider; - - /** - * List of listeners to be notified when a change occurred in remote control - * access. - */ - private List<RemoteControlListener> listeners = - new ArrayList<RemoteControlListener>(); - - /** * Initializes a new <tt>OperationSetDesktopSharingClientJabberImpl</tt>. * * @param parentProvider the Jabber <tt>ProtocolProviderService</tt> @@ -57,67 +34,7 @@ public class OperationSetDesktopSharingClientJabberImpl public OperationSetDesktopSharingClientJabberImpl( ProtocolProviderServiceJabberImpl parentProvider) { - this.parentProvider = parentProvider; - } - - /** - * Fire a <tt>RemoteControlGrantedEvent</tt> to all registered listeners. - */ - public void fireRemoteControlGranted() - { - RemoteControlGrantedEvent event = new RemoteControlGrantedEvent(this); - - for (RemoteControlListener l : listeners) - { - l.remoteControlGranted(event); - } - } - - /** - * Fire a <tt>RemoteControlGrantedEvent</tt> to all registered listeners. - */ - public void fireRemoteControlRevoked() - { - RemoteControlRevokedEvent event = new RemoteControlRevokedEvent(this); - - for (RemoteControlListener l : listeners) - { - l.remoteControlRevoked(event); - } - } - - /** - * Add a <tt>RemoteControlListener</tt> to be notified when remote peer - * accept to give us full control. - * - * @param listener <tt>RemoteControlListener</tt> to add - */ - public void addRemoteControlListener(RemoteControlListener listener) - { - if (logger.isInfoEnabled()) - logger.info("Enable remote control"); - - if (!listeners.contains(listener)) - { - listeners.add(listener); - } - } - - /** - * Remove a <tt>RemoteControlListener</tt> to be notified when remote peer - * accept/revoke to give us full control. - * - * @param listener <tt>RemoteControlListener</tt> to remove - */ - public void removeRemoteControlListener(RemoteControlListener listener) - { - if (logger.isInfoEnabled()) - logger.info("Disable remote control"); - - if (listeners.contains(listener)) - { - listeners.remove(listener); - } + super(parentProvider); } /** @@ -185,4 +102,4 @@ public class OperationSetDesktopSharingClientJabberImpl inputIQ.addRemoteControl(payload); parentProvider.getConnection().sendPacket(inputIQ); } -}
\ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingClientSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingClientSipImpl.java index 6d32632..8f654dd 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingClientSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingClientSipImpl.java @@ -8,7 +8,6 @@ package net.java.sip.communicator.impl.protocol.sip; import java.io.*; import java.text.*; -import java.util.List; // disambiguation import java.util.*; import java.awt.*; import java.awt.event.*; @@ -30,13 +29,14 @@ import net.java.sip.communicator.util.*; * @author Sebastien Vincent */ public class OperationSetDesktopSharingClientSipImpl - implements OperationSetDesktopSharingClient + extends AbstractOperationSetDesktopSharingClient + <ProtocolProviderServiceSipImpl> { /** * Our class logger. */ - private static final Logger logger = Logger - .getLogger(OperationSetDesktopSharingClientSipImpl.class); + private static final Logger logger + = Logger.getLogger(OperationSetDesktopSharingClientSipImpl.class); /** * The <tt>CallPeerListener</tt> which listens to modifications in the @@ -57,8 +57,8 @@ public class OperationSetDesktopSharingClientSipImpl CallPeer peer = evt.getSourceCallPeer(); CallPeerState state = peer.getState(); - if(state != null && (state.equals(CallPeerState.DISCONNECTED) || - state.equals(CallPeerState.FAILED))) + if (CallPeerState.DISCONNECTED.equals(state) + || CallPeerState.FAILED.equals(state)) { /* if the peer is disconnected or call has failed, remove * corresponding subscription. @@ -76,13 +76,6 @@ public class OperationSetDesktopSharingClientSipImpl }; /** - * List of listeners to be notified when a change occurred in remote control - * access. - */ - private List<RemoteControlListener> listeners = - new ArrayList<RemoteControlListener>(); - - /** * The <tt>EventPackageNotifier</tt> which implements remote-control * event-package notifier support on behalf of this * <tt>OperationSetDesktopSharingClient</tt> instance. @@ -90,13 +83,6 @@ public class OperationSetDesktopSharingClientSipImpl private final EventPackageNotifier notifier; /** - * The SIP <tt>ProtocolProviderService</tt> implementation which created - * this instance and for which telephony conferencing services are being - * provided by this instance. - */ - private final ProtocolProviderServiceSipImpl parentProvider; - - /** * The <tt>Timer</tt> which executes delayed tasks scheduled by * {@link #notifier}. */ @@ -105,7 +91,7 @@ public class OperationSetDesktopSharingClientSipImpl /** * List of SIP NOTIFY messages. */ - private Queue<String> inputEvents = new LinkedList<String>(); + private final Queue<String> inputEvents = new LinkedList<String>(); /** * Synchronization object for {@link #inputEvents} access. @@ -122,38 +108,42 @@ public class OperationSetDesktopSharingClientSipImpl public OperationSetDesktopSharingClientSipImpl( ProtocolProviderServiceSipImpl parentProvider) { - this.parentProvider = parentProvider; - - this.notifier = new EventPackageNotifier( - this.parentProvider, - DesktopSharingProtocolSipImpl.EVENT_PACKAGE, - DesktopSharingProtocolSipImpl.SUBSCRIPTION_DURATION, - DesktopSharingProtocolSipImpl.CONTENT_SUB_TYPE, - this.timer) - { - protected Subscription createSubscription( - Address fromAddress, - String eventId) + super(parentProvider); + + notifier + = new EventPackageNotifier( + this.parentProvider, + DesktopSharingProtocolSipImpl.EVENT_PACKAGE, + DesktopSharingProtocolSipImpl.SUBSCRIPTION_DURATION, + DesktopSharingProtocolSipImpl.CONTENT_SUB_TYPE, + this.timer) { - /* new subscription received */ - fireRemoteControlGranted(); + protected Subscription createSubscription( + Address fromAddress, + String eventId) + { + /* new subscription received */ + fireRemoteControlGranted(); - return - new RemoteControlNotifierSubscription( - fromAddress, - eventId); - } + return + new RemoteControlNotifierSubscription( + fromAddress, + eventId); + } - protected void removeSubscription( - Response response, - String eventId, - ClientTransaction clientTransaction) - { - super.removeSubscription(response, eventId, clientTransaction); + protected void removeSubscription( + Response response, + String eventId, + ClientTransaction clientTransaction) + { + super.removeSubscription( + response, + eventId, + clientTransaction); - fireRemoteControlRevoked(); - } - }; + fireRemoteControlRevoked(); + } + }; } /** @@ -203,34 +193,27 @@ public class OperationSetDesktopSharingClientSipImpl /* build a SIP NOTIFY with the corresponding keyboard event * and send it */ - String msg = null; - int keycode = event.getKeyCode(); - int key = event.getKeyChar(); - - if(key != KeyEvent.CHAR_UNDEFINED) - { - keycode = event.getKeyChar(); - } - else - { - keycode = event.getKeyCode(); - } + int keyChar = event.getKeyChar(); + int keyCode + = (keyChar == KeyEvent.CHAR_UNDEFINED) + ? event.getKeyCode() + : keyChar; - if(keycode == 0) - { + if (keyCode == 0) return; - } + + String msg; switch(event.getID()) { case KeyEvent.KEY_TYPED: - msg = DesktopSharingProtocolSipImpl.getKeyTypedXML(keycode); + msg = DesktopSharingProtocolSipImpl.getKeyTypedXML(keyCode); break; case KeyEvent.KEY_PRESSED: - msg = DesktopSharingProtocolSipImpl.getKeyPressedXML(keycode); + msg = DesktopSharingProtocolSipImpl.getKeyPressedXML(keyCode); break; case KeyEvent.KEY_RELEASED: - msg = DesktopSharingProtocolSipImpl.getKeyReleasedXML(keycode); + msg = DesktopSharingProtocolSipImpl.getKeyReleasedXML(keyCode); break; default: /* ignore */ @@ -327,58 +310,6 @@ public class OperationSetDesktopSharingClientSipImpl } /** - * Fire a <tt>RemoteControlGrantedEvent</tt> to all registered listeners. - */ - public void fireRemoteControlGranted() - { - RemoteControlGrantedEvent event = new RemoteControlGrantedEvent(this); - for(RemoteControlListener l : listeners) - { - l.remoteControlGranted(event); - } - } - - /** - * Fire a <tt>RemoteControlGrantedEvent</tt> to all registered listeners. - */ - public void fireRemoteControlRevoked() - { - RemoteControlRevokedEvent event = new RemoteControlRevokedEvent(this); - for(RemoteControlListener l : listeners) - { - l.remoteControlRevoked(event); - } - } - - /** - * Add a <tt>RemoteControlListener</tt> to be notified when remote peer - * accept to give us full control. - * - * @param listener <tt>RemoteControlListener</tt> to add - */ - public void addRemoteControlListener(RemoteControlListener listener) - { - if(!listeners.contains(listener)) - { - listeners.add(listener); - } - } - - /** - * Remove a <tt>RemoteControlListener</tt> to be notified when remote peer - * accept/revoke to give us full control. - * - * @param listener <tt>RemoteControlListener</tt> to remove - */ - public void removeRemoteControlListener(RemoteControlListener listener) - { - if(listeners.contains(listener)) - { - listeners.remove(listener); - } - } - - /** * Implements <tt>EventPackageNotifier.Subscription</tt> in order to * represent a subscription created by a remote <tt>CallPeer</tt> * to the remote-control event package of a local <tt>Call</tt>. @@ -503,14 +434,16 @@ public class OperationSetDesktopSharingClientSipImpl if (dialog != null) { OperationSetBasicTelephony<?> basicTelephony - = parentProvider.getOperationSet( + = parentProvider.getOperationSet( OperationSetBasicTelephony.class); if (basicTelephony != null) { - callPeer = - ((OperationSetBasicTelephonySipImpl)basicTelephony) - .getActiveCallsRepository().findCallPeer(dialog); + callPeer + = ((OperationSetBasicTelephonySipImpl) + basicTelephony) + .getActiveCallsRepository() + .findCallPeer(dialog); if (callPeer != null) callPeer.addCallPeerListener(callPeerListener); diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java index 6afa2fb..178ec1b 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java @@ -195,11 +195,14 @@ public class OperationSetDesktopSharingServerSipImpl { CallSipImpl call = (CallSipImpl)super.createVideoCall(callee, device); CallPeerSipImpl callPeer = call.getCallPeers().next(); + callPeer.addMethodProcessorListener(this); callPeer.addCallPeerListener(callPeerListener); - size = (((VideoMediaFormat)call.getDefaultDevice(MediaType.VIDEO). - getFormat()).getSize()); + size + = (((VideoMediaFormat) + call.getDefaultDevice(MediaType.VIDEO).getFormat()) + .getSize()); origin = getOriginForMediaDevice(device); return call; } @@ -214,7 +217,7 @@ public class OperationSetDesktopSharingServerSipImpl { RemoteControlSubscriberSubscription subscription = new RemoteControlSubscriberSubscription( - (CallPeerSipImpl)callPeer); + (CallPeerSipImpl) callPeer); try { @@ -225,7 +228,6 @@ public class OperationSetDesktopSharingServerSipImpl logger.error( "Failed to create or send a remote-control subscription", ofe); - return; } } @@ -240,8 +242,10 @@ public class OperationSetDesktopSharingServerSipImpl /* unsubscribe */ try { - Address addr = parentProvider.parseAddressString( - callPeer.getAddress()); + Address addr + = parentProvider.parseAddressString( + callPeer.getAddress()); + subscriber.unsubscribe(addr, false); } catch(ParseException ex) diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java index 542801d..43c1200 100644 --- a/src/net/java/sip/communicator/service/neomedia/MediaService.java +++ b/src/net/java/sip/communicator/service/neomedia/MediaService.java @@ -238,8 +238,9 @@ public interface MediaService * @param x new x coordinate origin * @param y new y coordinate origin */ - public void movePartialDesktopStreaming(MediaDevice mediaDevice, int x, - int y); + public void movePartialDesktopStreaming( + MediaDevice mediaDevice, + int x, int y); /** * If the <tt>MediaDevice</tt> corresponds to partial desktop streaming diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetDesktopSharingClient.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetDesktopSharingClient.java new file mode 100644 index 0000000..205c67e --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetDesktopSharingClient.java @@ -0,0 +1,183 @@ +/* + * 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; + +import java.lang.ref.*; +import java.util.*; + +import net.java.sip.communicator.service.protocol.event.*; + +/** + * Represents a default/base implementation of + * <tt>OperationSetDesktopSharingClient</tt> which attempts to make it easier + * for implementers to provide complete solutions while focusing on + * implementation-specific functionality. + * + * @param <T> + * + * @author Sebastien Vincent + * @author Lyubomir Marinov + */ +public abstract class AbstractOperationSetDesktopSharingClient + <T extends ProtocolProviderService> + implements OperationSetDesktopSharingClient +{ + + /** + * The list of <tt>RemoteControlListener</tt>s to be notified when a change + * in remote control access occurs. + */ + private final List<WeakReference<RemoteControlListener>> listeners + = new ArrayList<WeakReference<RemoteControlListener>>(); + + /** + * The <tt>ProtocolProviderService</tt> implementation which created this + * instance and for which telephony conferencing services are being provided + * by this instance. + */ + protected final T parentProvider; + + /** + * Initializes a new <tt>AbstractOperationSetDesktopSharing</tt> instance + * which is to be provided by a specific <tt>ProtocolProviderService. + * + * @param parentProvider the <tt>ProtocolProviderService</tt> implementation + * which is creating the new instance and for which telephony conferencing + * services are being provided by this instance + */ + protected AbstractOperationSetDesktopSharingClient(T parentProvider) + { + this.parentProvider = parentProvider; + } + + /** + * Adds a <tt>RemoteControlListener</tt> to be notified when the remote peer + * accepts to give us full control of their desktop. + * <p> + * The default implementation of + * <tt>AbstractOperationSetDesktopSharingClient</tt> adds a + * <tt>WeakReference</tt> to the specified <tt>RemoteControlListener</tt> in + * order to avoid memory leaks because of code which calls + * <tt>addRemoteControlListener</tt> and never calls + * <tt>removeRemoteControlListener</tt>. + * </p> + * + * @param listener the <tt>RemoteControlListener</tt> to add + */ + public void addRemoteControlListener(RemoteControlListener listener) + { + synchronized (listeners) + { + Iterator<WeakReference<RemoteControlListener>> i + = listeners.iterator(); + boolean contains = false; + + while (i.hasNext()) + { + RemoteControlListener l = i.next().get(); + + if (l == null) + i.remove(); + else if (l.equals(listener)) + contains = true; + } + if (!contains) + { + listeners.add( + new WeakReference<RemoteControlListener>(listener)); + } + } + } + + /** + * Fires a <tt>RemoteControlGrantedEvent</tt> to all registered listeners. + */ + public void fireRemoteControlGranted() + { + List<RemoteControlListener> listeners = getListeners(); + + if (!listeners.isEmpty()) + { + RemoteControlGrantedEvent event + = new RemoteControlGrantedEvent(this); + + for(RemoteControlListener l : listeners) + l.remoteControlGranted(event); + } + } + + /** + * Fires a <tt>RemoteControlGrantedEvent</tt> to all registered listeners. + */ + public void fireRemoteControlRevoked() + { + List<RemoteControlListener> listeners = getListeners(); + + if (!listeners.isEmpty()) + { + RemoteControlRevokedEvent event + = new RemoteControlRevokedEvent(this); + + for(RemoteControlListener l : listeners) + l.remoteControlRevoked(event); + } + } + + /** + * Gets a list of <tt>RemoteControlListener</tt>s to be notified of remote + * control access changes. + * + * @return a list of <tt>RemoteControlListener</tt>s to be notifed of remote + * control access changes + */ + protected List<RemoteControlListener> getListeners() + { + List<RemoteControlListener> listeners; + + synchronized (this.listeners) + { + Iterator<WeakReference<RemoteControlListener>> i + = this.listeners.iterator(); + listeners + = new ArrayList<RemoteControlListener>(this.listeners.size()); + + while (i.hasNext()) + { + RemoteControlListener l = i.next().get(); + + if (l == null) + i.remove(); + else + listeners.add(l); + } + } + return listeners; + } + + /** + * Removes a <tt>RemoteControlListener</tt> to be notified when remote peer + * accept/revoke to give us full control. + * + * @param listener <tt>RemoteControlListener</tt> to remove + */ + public void removeRemoteControlListener(RemoteControlListener listener) + { + synchronized (listeners) + { + Iterator<WeakReference<RemoteControlListener>> i + = listeners.iterator(); + + while (i.hasNext()) + { + RemoteControlListener l = i.next().get(); + + if ((l == null) || l.equals(listener)) + i.remove(); + } + } + } +} diff --git a/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java b/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java index 5772714..23b829a 100644 --- a/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java +++ b/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java @@ -92,8 +92,6 @@ public interface AdHocChatRoom * * @return a <tt>List</tt> of <tt>Contact</tt>s instances * corresponding to all room members. - * @throws OperationFailedException if we fail retrieving the list of room - * participants. */ public List<Contact> getParticipants(); diff --git a/src/net/java/sip/communicator/service/protocol/event/RemoteControlGrantedEvent.java b/src/net/java/sip/communicator/service/protocol/event/RemoteControlGrantedEvent.java index c51d5cc..b10f675 100644 --- a/src/net/java/sip/communicator/service/protocol/event/RemoteControlGrantedEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/RemoteControlGrantedEvent.java @@ -4,7 +4,7 @@ import java.util.*; /** * Event that notify that remote control feature has been granted. This is used - * in desktop sharing related usage. After rights beeing granted, local + * in desktop sharing related usage. After rights being granted, local * peer should notify keyboard and mouse events to remote peer. * * @author Sebastien Vincent |