Adds new improved security interface.

cusax-fix
Yana Stamcheva 14 years ago
parent f26b85ff9e
commit f9a8da4458

@ -203,4 +203,13 @@ service.gui.SEARCH_BORDER_GRADIENT=ACACAC
service.gui.SEARCH_FOREGROUND=000000
# The default text foreground of the search field
service.gui.SEARCH_DEFAULT_FOREGROUND=ACACAC
service.gui.SEARCH_DEFAULT_FOREGROUND=ACACAC
# The security on status color.
service.gui.SECURITY_ON=6FC93C
# The security off status color.
service.gui.SECURITY_OFF=ED0000
# Going secure status color.
service.gui.GOING_SECURE=FFC01B

@ -89,3 +89,5 @@ net.java.sip.communicator.util.dns.DS_ROOT.1=. IN DS 19036 8 2 49AAC11D7B6F64467
plugin.jabberaccregwizz.NEW_ACCOUNT_DEFAULT_SERVER=jit.si
net.java.sip.communicator.service.neomedia.SDES_CIPHER_SUITES=AES_CM_128_HMAC_SHA1_80,AES_CM_128_HMAC_SHA1_32
impl.gui.PARANOIA_UI=false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 585 B

After

Width:  |  Height:  |  Size: 655 B

@ -120,12 +120,11 @@ service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} has changed the subject to {1}
service.gui.CHOOSE_CONTACT=Choose contact
service.gui.CHOOSE_ACCOUNT=Please select one of the listed accounts.
service.gui.SHOW_MORE_TOOLTIP=Click to show more results
servoce.gui.CLEAR=Clear
service.gui.CLOSE=Cl&ose
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=You have received a new message less than 2 seconds ago. Are you sure you want to close this chat?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=You have active file transfers. Are you sure you want to cancel them?
service.gui.COMPARE_WITH_PARTNER=Compare with partner and click the padlock to confirm.
# keep the following string short
service.gui.COMPARE_WITH_PARTNER_SHORT=Compare with partner: {0}
servoce.gui.CONFIRM=Confirm
service.gui.CONNECTED_STATUS=Connected
service.gui.CONNECTING=Connecting...
service.gui.CONNECTING_STATUS=Connecting
@ -611,6 +610,29 @@ service.gui.AUTO_ANSWER_DESCR_VLUE=leave empty for any
service.gui.AUTO_ANSWER_FWD_CALLS=Forward Calls
service.gui.AUTO_ANSWER_FWD_CALLS_TO=Forward all calls to the following number or URI:
service.gui.security.SECURE_AUDIO=Secure audio
service.gui.security.AUDIO_NOT_SECURED=Audio not secured
service.gui.security.SECURE_VIDEO=Secure video
service.gui.security.VIDEO_NOT_SECURED=Video not secured
service.gui.security.NO_VIDEO=No video
service.gui.security.CIPHER=Cipher: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Call secured. Fore more information press here.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Call not secured. Fore more information press here.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Press here to compare security secret with your partner.
service.gui.security.COMPARE_WITH_PARTNER=Compare with partner and click the padlock to confirm.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Compare with partner:
service.gui.security.STRING_COMPARED=String compared!
service.gui.security.SAS_INFO_TOOLTIP=\
<html>In order to be completely secured you<br/>\
need to verbally <b>compare</b> the short<br/>\
authentication string here left with your<br/>\
partner and press the confirm button when the <br/>\
string is verified.<br/><br/\
If you clear the confirmation, you'll be asked to verify<br/>\
next time when you call this partner.</html>
service.gui.security.SECURITY_ALERT=Trying to secure call. Will disconnect in
service.gui.avatar.CHOOSE_ICON=Choose picture
service.gui.avatar.REMOVE_ICON=Remove current picture
service.gui.avatar.CLEAR_RECENT=Clear recent pictures

@ -104,7 +104,7 @@ else if (CallPeerState.isOnHold(newState))
renderer.getCallPanel().updateHoldButtonState();
}
renderer.setPeerState(newStateString);
renderer.setPeerState(newState, newStateString);
String reasonString = evt.getReasonString();
if (reasonString != null)

@ -8,6 +8,7 @@
import java.awt.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
/**
@ -37,9 +38,10 @@ public interface CallPeerRenderer
* Sets the state of the contained call peer by specifying the
* state name.
*
* @param peerState the peer state
* @param state the state of the contained call peer
*/
public void setPeerState(String state);
public void setPeerState(CallPeerState peerState, String state);
/**
* Sets the reason of a call failure if one occurs. The renderer should
@ -77,6 +79,11 @@ public interface CallPeerRenderer
*/
public void securityOff(CallPeerSecurityOffEvent evt);
/**
* Indicates that the security status is pending confirmation.
*/
public void securityPending();
/**
* Indicates that the security is timeouted, is not supported by the
* other end.
@ -148,4 +155,12 @@ public interface CallPeerRenderer
* @return the video handler associated with this call peer renderer
*/
public UIVideoHandler getVideoHandler();
/**
* Shows/hides the security panel.
*
* @param isVisible <tt>true</tt> to show the security panel, <tt>false</tt>
* to hide it
*/
public void setSecurityPanelVisible(boolean isVisible);
}

@ -14,9 +14,11 @@
import javax.swing.*;
import javax.swing.text.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.call.conference.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.resources.*;
@ -65,7 +67,7 @@ public class OneToOneCallPeerPanel
/**
* The security status of the peer
*/
private SecurityStatusLabel securityStatusLabel;
private SecurityStatusLabel securityStatusLabel = new SecurityStatusLabel();
/**
* The label showing whether the voice has been set to mute.
@ -199,6 +201,7 @@ public OneToOneCallPeerPanel( CallRenderer callRenderer,
this.callPeer = callPeer;
this.peerName = callPeer.getDisplayName();
this.videoContainers = videoContainers;
this.securityPanel = SecurityPanel.create(this, callPeer, null);
if (vHandler == null)
videoHandler
@ -212,11 +215,6 @@ public OneToOneCallPeerPanel( CallRenderer callRenderer,
videoHandler.addVideoListener();
videoHandler.addRemoteControlListener();
securityStatusLabel = new SecurityStatusLabel(
callRenderer.getCallContainer().getCallWindow().getFrame(),
new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_BUTTON_OFF)));
photoLabel = new JLabel(getPhotoLabelIcon());
center = createCenter(videoContainers);
statusBar = createStatusBar();
@ -382,6 +380,8 @@ private Component createStatusBar()
statusPanel.add(muteStatusLabel, constraints);
constraints.gridx++;
callStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 3, 2, 5));
statusPanel.add(callStatusLabel, constraints);
constraints.gridx++;
@ -509,7 +509,6 @@ private static class PeerStatusPanel
public PeerStatusPanel(LayoutManager layout)
{
super(layout);
this.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
}
/**
@ -600,11 +599,25 @@ private ImageIcon getPhotoLabelIcon()
* Sets the state of the contained call peer by specifying the
* state name and icon.
*
* @param peerState the peer state
* @param state the state of the contained call peer
*/
public void setPeerState(String state)
public void setPeerState(CallPeerState peerState, String state)
{
this.callStatusLabel.setText(state);
if (peerState == CallPeerState.CONNECTED)
{
initSecurityStatusLabel();
if(Boolean.parseBoolean(GuiActivator.getResources()
.getSettingsString("impl.gui.PARANOIA_UI")))
{
securityPanel = new ParanoiaTimerSecurityPanel();
setSecurityPanelVisible(true);
}
}
}
/**
@ -616,10 +629,18 @@ public void setPeerState(String state)
public void setMute(boolean isMute)
{
if(isMute)
{
muteStatusLabel.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.MUTE_STATUS_ICON)));
muteStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 3, 2, 3));
}
else
{
muteStatusLabel.setIcon(null);
muteStatusLabel.setBorder(
BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
this.revalidate();
this.repaint();
@ -632,10 +653,18 @@ public void setMute(boolean isMute)
public void setOnHold(boolean isOnHold)
{
if(isOnHold)
{
holdStatusLabel.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.HOLD_STATUS_ICON)));
holdStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 3, 2, 3));
}
else
{
holdStatusLabel.setIcon(null);
holdStatusLabel.setBorder(
BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
this.revalidate();
this.repaint();
@ -650,43 +679,48 @@ public void setOnHold(boolean isOnHold)
*/
public void securityOn(CallPeerSecurityOnEvent evt)
{
if((evt.getSecurityController().requiresSecureSignalingTransport()
&& callPeer.getProtocolProvider().isSignalingTransportSecure())
|| !evt.getSecurityController().requiresSecureSignalingTransport())
// If the securityOn is called without a specific event, we'll just set
// the security label status to on.
if (evt == null)
{
securityImageID = ImageLoader.SECURE_BUTTON_ON;
securityStatusLabel.setIcon(new ImageIcon(ImageLoader
.getImage(securityImageID)));
securityStatusLabel.setSecurityOn();
return;
}
//set common encryption properties
securityStatusLabel.setEncryptionCipher(evt.getCipher());
switch (evt.getSessionType())
SrtpControl srtpControl = evt.getSecurityController();
if ((srtpControl.requiresSecureSignalingTransport()
&& callPeer.getProtocolProvider().isSignalingTransportSecure())
|| !srtpControl.requiresSecureSignalingTransport())
{
case CallPeerSecurityStatusEvent.AUDIO_SESSION:
securityStatusLabel.setAudioSecurityOn(true);
break;
case CallPeerSecurityStatusEvent.VIDEO_SESSION:
securityStatusLabel.setVideoSecurityOn(true);
break;
if (srtpControl instanceof ZrtpControl)
{
securityStatusLabel.setText("zrtp");
if (!((ZrtpControl) srtpControl).isSecurityVerified())
securityStatusLabel.setSecurityPending();
else
securityStatusLabel.setSecurityOn();
}
else
securityStatusLabel.setSecurityOn();
}
//set encryption specific options
if (securityPanel == null)
// if we have some other panel, using other control
if(!srtpControl.getClass().isInstance(
securityPanel.getSecurityControl()))
{
securityPanel = SecurityPanel.create(evt.getSecurityController());
GridBagConstraints constraints = new GridBagConstraints();
setSecurityPanelVisible(false);
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 2;
constraints.weightx = 0;
constraints.weighty = 0;
constraints.insets = new Insets(5, 0, 0, 0);
this.add(securityPanel, constraints);
securityPanel
= SecurityPanel.create(this, callPeer, srtpControl);
}
securityPanel.refreshStates();
securityPanel.securityOn(evt);
if (srtpControl instanceof ZrtpControl
&& !((ZrtpControl) srtpControl).isSecurityVerified())
setSecurityPanelVisible(true);
this.revalidate();
}
@ -696,27 +730,21 @@ public void securityOn(CallPeerSecurityOnEvent evt)
*/
public void securityOff(CallPeerSecurityOffEvent evt)
{
securityImageID = ImageLoader.SECURE_BUTTON_OFF;
securityStatusLabel.setIcon(new ImageIcon(ImageLoader
.getImage(securityImageID)));
securityStatusLabel.setText("");
securityStatusLabel.setSecurityOff();
if (securityStatusLabel.getBorder() == null)
securityStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 5, 2, 3));
switch (evt.getSessionType())
{
case CallPeerSecurityStatusEvent.AUDIO_SESSION:
securityStatusLabel.setAudioSecurityOn(false);
break;
case CallPeerSecurityStatusEvent.VIDEO_SESSION:
securityStatusLabel.setVideoSecurityOn(false);
break;
}
securityPanel.securityOff(evt);
}
if (securityPanel != null
&& !securityStatusLabel.isAudioSecurityOn()
&& !securityStatusLabel.isVideoSecurityOn())
{
securityPanel.getParent().remove(securityPanel);
securityPanel = null;
}
/**
* Indicates that the security status is pending confirmation.
*/
public void securityPending()
{
securityStatusLabel.setSecurityPending();
}
/**
@ -726,7 +754,8 @@ public void securityOff(CallPeerSecurityOffEvent evt)
*/
public void securityTimeout(CallPeerSecurityTimeoutEvent evt)
{
if (securityPanel != null)
securityPanel.securityTimeout(evt);
}
/**
@ -763,6 +792,9 @@ public CallPanel getCallPanel()
public void printDTMFTone(char dtmfChar)
{
dtmfLabel.setText(dtmfLabel.getText() + dtmfChar);
if (dtmfLabel.getBorder() == null)
dtmfLabel.setBorder(
BorderFactory.createEmptyBorder(2, 1, 2, 5));
}
/**
@ -1041,175 +1073,6 @@ public CallPeer getCallPeer()
}
}
/**
* The Mouse listener for local video. It is responsible for dragging local
* video.
*/
// private class LocalVideoMouseListener
// implements MouseListener,
// MouseMotionListener
// {
// /**
// * Indicates if we're currently during a drag operation.
// */
// private boolean inDrag = false;
//
// /**
// * The previous x coordinate of the drag.
// */
// private int previousX = 0;
//
// /**
// * The previous y coordinate of the drag.
// */
// private int previousY = 0;
//
// /**
// * Indicates that the mouse has been dragged.
// *
// * @param event the <tt>MouseEvent</tt> that notified us
// */
// public void mouseDragged(MouseEvent event)
// {
// Point p = event.getPoint();
//
// if (inDrag)
// {
// Component c = (Component) event.getSource();
//
// int newX = c.getX() + p.x - previousX;
// int newY = c.getY() + p.y - previousY;
//
// Component remoteContainer;
// if (remoteVideo != null)
// remoteContainer = remoteVideo;
// else
// synchronized (videoContainers)
// {
// // If there's no remote video we limit the drag to the
// // parent video container.
// if (videoContainers != null
// && videoContainers.size() > 0)
// remoteContainer = videoContainers.get(
// videoContainers.size() - 1);
// else
// // In the case no video container is available
// // we just limit the drag to this panel.
// remoteContainer = OneToOneCallPeerPanel.this;
// }
//
// int minX = remoteContainer.getX();
// int maxX = remoteContainer.getX() + remoteContainer.getWidth();
// int minY = remoteContainer.getY();
// int maxY = remoteContainer.getY() + remoteContainer.getHeight();
//
// if (newX < minX)
// newX = minX;
//
// if (newX + c.getWidth() > maxX)
// newX = maxX - c.getWidth();
//
// if (newY < minY)
// newY = minY;
//
// if (newY + c.getHeight() > maxY)
// newY = maxY - c.getHeight();
//
// c.setLocation(newX, newY);
// if (closeButton.isVisible())
// closeButton.setVisible(false);
// }
// }
//
// public void mouseMoved(MouseEvent event) {}
//
// public void mouseClicked(MouseEvent event) {}
//
// public void mouseEntered(MouseEvent event) {}
//
// public void mouseExited(MouseEvent event) {}
//
// /**
// * Indicates that the mouse has been pressed.
// *
// * @param event the <tt>MouseEvent</tt> that notified us
// */
// public void mousePressed(MouseEvent event)
// {
// Point p = event.getPoint();
//
// previousX = p.x;
// previousY = p.y;
// inDrag = true;
// }
//
// /**
// * Indicates that the mouse has been released.
// *
// * @param event the <tt>MouseEvent</tt> that notified us
// */
// public void mouseReleased(MouseEvent event)
// {
// inDrag = false;
// previousX = 0;
// previousY = 0;
//
// if (!closeButton.isVisible())
// {
// Component c = (Component) event.getSource();
// closeButton.setLocation(
// c.getX() + c.getWidth() - closeButton.getWidth() - 3,
// c.getY() + 3);
// closeButton.setVisible(true);
// }
// }
// }
// private class CloseButton
// extends Label
// implements MouseListener
// {
// private static final long serialVersionUID = 0L;
//
// Image image = ImageLoader.getImage(ImageLoader.CLOSE_VIDEO);
//
// public CloseButton()
// {
// int buttonWidth = image.getWidth(this) + 5;
// int buttonHeight = image.getHeight(this) + 5;
//
// setPreferredSize(new Dimension(buttonWidth, buttonHeight));
// setSize(new Dimension(buttonWidth, buttonHeight));
//
// this.addMouseListener(this);
// }
//
// public void paint(Graphics g)
// {
// g.setColor(Color.GRAY);
// g.fillRect(0, 0, getWidth(), getHeight());
// g.drawImage(image,
// getWidth()/2 - image.getWidth(this)/2,
// getHeight()/2 - image.getHeight(this)/2, this);
// }
//
// public void mouseClicked(MouseEvent event)
// {
// setLocalVideoVisible(false);
//
// callRenderer.getCallContainer()
// .setShowHideVideoButtonSelected(false);
// }
//
// public void mouseEntered(MouseEvent event) {}
//
// public void mouseExited(MouseEvent event) {}
//
// public void mousePressed(MouseEvent event) {}
//
// public void mouseReleased(MouseEvent event) {}
// }
/**
* Reloads all icons.
*/
@ -1254,63 +1117,6 @@ public void loadSkin()
public void setLocalVideoVisible(boolean isVisible)
{
videoHandler.setLocalVideoVisible(isVisible);
// synchronized (videoContainers)
// {
// this.localVideoVisible = isVisible;
//
// if (isVisible
// != callRenderer.getCallContainer()
// .isShowHideVideoButtonSelected())
// {
// callRenderer.getCallContainer()
// .setShowHideVideoButtonSelected(isVisible);
// }
//
// int videoContainerCount;
//
// if ((videoTelephony != null)
// && ((videoContainerCount = videoContainers.size()) > 0))
// {
// Container videoContainer
// = videoContainers.get(videoContainerCount - 1);
//
// if (localVideo != null)
// {
// if (isVisible)
// {
// Container localVideoParent = localVideo.getParent();
//
// if (localVideoParent != null)
// localVideoParent.remove(localVideo);
//
// Container closeButtonParent
// = closeButton.getParent();
//
// if (closeButtonParent != null)
// closeButtonParent.remove(closeButton);
//
// videoContainer.add(localVideo, VideoLayout.LOCAL, 0);
// videoContainer.add(
// closeButton,
// VideoLayout.CLOSE_LOCAL_BUTTON,
// 0);
// }
// else
// {
// videoContainer.remove(localVideo);
// videoContainer.remove(closeButton);
// }
//
// /*
// * Just like #handleVideoEvent(VideoEvent, Container) says,
// * we have to be explicit in order to achieve a proper
// * layout and an up-to-date painting.
// */
// videoContainer.validate();
// videoContainer.repaint();
// }
// }
// }
}
/**
@ -1353,4 +1159,174 @@ public UIVideoHandler getVideoHandler()
{
return videoHandler;
}
/**
* Initializes the security status label, shown in the call status bar.
*/
private void initSecurityStatusLabel()
{
securityStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 5, 2, 5));
securityStatusLabel.setSecurityOff();
securityStatusLabel.addMouseListener(new MouseAdapter()
{
/**
* Invoked when a mouse button has been pressed on a component.
*/
public void mousePressed(MouseEvent e)
{
// Only show the security details if the security is on.
if (callPeer.getCurrentSecuritySettings()
instanceof CallPeerSecurityOnEvent)
{
setSecurityPanelVisible(!callRenderer.getCallContainer()
.getCallWindow().getFrame().getGlassPane().isVisible());
}
}
});
}
/**
* Shows/hides the security panel.
*
* @param isVisible <tt>true</tt> to show the security panel, <tt>false</tt>
* to hide it
*/
public void setSecurityPanelVisible(boolean isVisible)
{
final JFrame callFrame = callRenderer.getCallContainer()
.getCallWindow().getFrame();
final JPanel glassPane = (JPanel) callFrame.getGlassPane();
if (!isVisible)
{
// Need to hide the security panel explicitly in order to keep the
// fade effect.
securityPanel.setVisible(false);
glassPane.setVisible(false);
glassPane.removeAll();
}
else
{
glassPane.setLayout(null);
glassPane.addMouseListener(new MouseListener()
{
public void mouseReleased(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mousePressed(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mouseExited(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mouseEntered(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mouseClicked(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
});
Point securityLabelPoint = securityStatusLabel.getLocation();
Point newPoint
= SwingUtilities.convertPoint(securityStatusLabel.getParent(),
securityLabelPoint.x, securityLabelPoint.y,
callFrame);
securityPanel.setBeginPoint(
new Point((int) newPoint.getX() + 15, 0));
securityPanel.setBounds(
0, (int) newPoint.getY() - 5, callFrame.getWidth(), 110);
glassPane.add(securityPanel);
// Need to show the security panel explicitly in order to keep the
// fade effect.
securityPanel.setVisible(true);
glassPane.setVisible(true);
glassPane.addComponentListener(new ComponentAdapter()
{
/**
* Invoked when the component's size changes.
*/
public void componentResized(ComponentEvent e)
{
if (glassPane.isVisible())
{
glassPane.setVisible(false);
callFrame.removeComponentListener(this);
}
}
});
}
}
/**
* Re-dispatches glass pane mouse events only in case they occur on the
* security panel.
*
* @param glassPane the glass pane
* @param e the mouse event in question
*/
private void redispatchMouseEvent(Component glassPane, MouseEvent e)
{
Point glassPanePoint = e.getPoint();
Point securityPanelPoint = SwingUtilities.convertPoint(
glassPane,
glassPanePoint,
securityPanel);
Component component;
Point componentPoint;
if (securityPanelPoint.y > 0)
{
component = securityPanel;
componentPoint = securityPanelPoint;
}
else
{
Container contentPane
= callRenderer.getCallContainer().getCallWindow()
.getFrame().getContentPane();
Point containerPoint = SwingUtilities.convertPoint(
glassPane,
glassPanePoint,
contentPane);
component = SwingUtilities.getDeepestComponentAt(contentPane,
containerPoint.x, containerPoint.y);
componentPoint = SwingUtilities.convertPoint(contentPane,
glassPanePoint, component);
}
if (component != null)
component.dispatchEvent(new MouseEvent( component,
e.getID(),
e.getWhen(),
e.getModifiers(),
componentPoint.x,
componentPoint.y,
e.getClickCount(),
e.isPopupTrigger()));
e.consume();
}
}

@ -0,0 +1,142 @@
/*
* 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.gui.main.call;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import javax.swing.*;
import java.awt.*;
import java.text.*;
import java.util.*;
import java.util.Timer;
/**
* @author Damian Minkov
* @author Yana Stamcheva
*/
public class ParanoiaTimerSecurityPanel
extends SecurityPanel<SrtpControl>
{
/**
* The security timer.
*/
private Timer timer = new Timer(true);
/**
* Creates an instance of this <tt>ParanoiaTimerSecurityPanel</tt>.
*/
ParanoiaTimerSecurityPanel()
{
super(null);
initComponents();
}
/**
* Initializes contained components.
*/
private void initComponents()
{
final SimpleDateFormat format = new SimpleDateFormat("mm:ss");
final Calendar c = Calendar.getInstance();
final JLabel counter = new JLabel();
counter.setForeground(Color.red);
counter.setFont(counter.getFont().deriveFont(
(float)(counter.getFont().getSize() + 5)));
setLayout(new GridBagLayout());
setBorder(
BorderFactory.createEmptyBorder(20, 20, 20, 20));
GridBagConstraints constraints = new GridBagConstraints();
JLabel messageLabel = new JLabel(GuiActivator.getResources()
.getI18NString("service.gui.security.SECURITY_ALERT"));
messageLabel.setForeground(Color.WHITE);
constraints.anchor = GridBagConstraints.CENTER;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 0;
add(messageLabel, constraints);
constraints.anchor = GridBagConstraints.CENTER;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 1;
add(counter, constraints);
ZrtpControl zrtpControl = null;
if (securityControl instanceof ZrtpControl)
zrtpControl = (ZrtpControl) securityControl;
int initialSeconds = 0;
if (zrtpControl != null)
initialSeconds = (int) zrtpControl.getTimeoutValue()/1000;
c.set(Calendar.HOUR, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, initialSeconds);
counter.setText(format.format(c.getTime()));
if (initialSeconds > 0)
timer.schedule(new TimerTask()
{
@Override
public void run()
{
c.add(Calendar.SECOND, -1);
counter.setText(format.format(c.getTime()));
}
}, 0, 1000);
}
/**
* Cancels the security timer.
*
* @param evt the security event of which we're notified
*/
public void securityOn(CallPeerSecurityOnEvent evt)
{
timer.cancel();
}
/**
* Nothing to do here.
*
* @param evt the security event of which we're notified
*/
public void securityOff(CallPeerSecurityOffEvent evt) {}
/**
* Indicates that the security is time-outed, is not supported by the
* other end.
* @param evt Details about the event that caused this message.
*/
public void securityTimeout(CallPeerSecurityTimeoutEvent evt)
{
timer.cancel();
// fail peer, call
if(evt.getSource() instanceof AbstractCallPeer)
{
AbstractCallPeer peer = (AbstractCallPeer)evt.getSource();
peer.setState(CallPeerState.FAILED, "Encryption Required!");
}
}
public void loadSkin()
{
}
}

@ -7,6 +7,8 @@
package net.java.sip.communicator.impl.gui.main.call;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
@ -15,10 +17,42 @@
*
* @author Ingo Bauersachs
*/
public abstract class SecurityPanel
extends TransparentPanel
public abstract class SecurityPanel<T extends SrtpControl>
extends FadeInBalloonPanel
implements Skinnable
{
/**
* The currently used security control.
*/
protected T securityControl;
/**
* Create security panel using the security control.
* @param securityControl
*/
public SecurityPanel(T securityControl)
{
this.securityControl = securityControl;
}
/**
* The currently used security control.
* @return
*/
public T getSecurityControl()
{
return securityControl;
}
/**
* The currently used security control.
* @return
*/
public void setSecurityControl(T securityControl)
{
this.securityControl = securityControl;
}
/**
* Creates the security panel depending on the concrete implementation of
* the passed security controller.
@ -29,23 +63,49 @@ public abstract class SecurityPanel
* controller or an {@link TransparentPanel} if the controller is
* unknown or does not have any controls to show.
*/
public static SecurityPanel create(SrtpControl srtpControl)
public static SecurityPanel create( CallPeerRenderer peerRenderer,
CallPeer callPeer,
SrtpControl srtpControl)
{
if(srtpControl instanceof ZrtpControl)
return new ZrtpSecurityPanel((ZrtpControl)srtpControl);
return new ZrtpSecurityPanel( peerRenderer,
callPeer,
(ZrtpControl)srtpControl);
return new SecurityPanel()
return new SecurityPanel<SrtpControl>(srtpControl)
{
public void loadSkin()
{}
public void refreshStates()
public void securityOn(CallPeerSecurityOnEvent evt)
{}
public void securityOff(CallPeerSecurityOffEvent evt)
{}
public void securityTimeout(CallPeerSecurityTimeoutEvent evt)
{}
};
}
/**
* Forces the panel to update the security information presented to the
* user.
* Indicates that the security is turned on.
*
* @param evt details about the event that caused this message.
*/
public abstract void securityOn(CallPeerSecurityOnEvent evt);
/**
* Indicates that the security is turned off.
*
* @param evt details about the event that caused this message.
*/
public abstract void securityOff(CallPeerSecurityOffEvent evt);
/**
* Indicates that the security is timeouted, is not supported by the
* other end.
* @param evt Details about the event that caused this message.
*/
public abstract void refreshStates();
public abstract void securityTimeout(CallPeerSecurityTimeoutEvent evt);
}

@ -10,8 +10,10 @@
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
/**
* The <tt>SecurityStatusLabel</tt> is meant to be used to visualize the audio
@ -22,7 +24,7 @@
*/
public class SecurityStatusLabel
extends JLabel
implements Skinnable
implements Skinnable
{
/**
* Serial version UID.
@ -30,157 +32,135 @@ public class SecurityStatusLabel
private static final long serialVersionUID = 0L;
/**
* Indicates the state of the audio security (on or off).
* The icon used for the not secured state.
*/
private boolean isAudioSecurityOn = false;
private static Icon securityOffIcon;
/**
* Indicates the state of the video security (on or off).
* The icon used for the secured state.
*/
private boolean isVideoSecurityOn = false;
private static Icon securityOnIcon;
/**
* The encryption cipher.
* The background used to indicate that the call is secured.
*/
private String encryptionCipher;
private final static Color securityOnBackground
= new Color(GuiActivator.getResources()
.getColor("service.gui.SECURITY_ON"));
/**
* The default security status icon.
* The background used to indicate that the call is not secured.
*/
private final Icon defaultIcon;
private final static Color securityOffBackground
= new Color(GuiActivator.getResources()
.getColor("service.gui.SECURITY_OFF"));
/**
* The parent window, where this component will be contained.
* The background used to indicate that the call is not secured.
*/
private final Window parentWindow;
private final static Color goingSecureBackground
= new Color(GuiActivator.getResources()
.getColor("service.gui.GOING_SECURE"));
/**
* Indicates security status.
*/
private boolean isSecure = false;
/**
* Creates an instance of <tt>SecurityStatusLabel</tt> by specifying the
* <tt>GuiCallPeer</tt>, the icon and the alignment to use for the label.
*/
public SecurityStatusLabel(Window parentWindow, Icon securityIcon)
public SecurityStatusLabel()
{
this.parentWindow = parentWindow;
this.defaultIcon = securityIcon;
loadSkin();
this.setHorizontalAlignment(JLabel.CENTER);
setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 3));
setForeground(Color.WHITE);
this.setToolTipText("Security status");
setHorizontalAlignment(JLabel.CENTER);
setHorizontalTextPosition(JLabel.LEFT);
}
/**
* Create an extended tooltip showing some more security details.
* @return the created tooltip
* Paints a custom background to better indicate security state.
*
* @param g the <tt>Graphics</tt> object
*/
public JToolTip createToolTip()
public void paintComponent(Graphics g)
{
ExtendedTooltip tip = new ExtendedTooltip(parentWindow, true);
g = g.create();
tip.setTitle("Security status");
ImageIcon audioStatusIcon;
String audioStatusString;
if (isAudioSecurityOn)
{
audioStatusIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_AUDIO_ON));
audioStatusString = "Audio security on.";
}
else
try
{
audioStatusIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_AUDIO_OFF));
audioStatusString = "Audio security off.";
AntialiasingManager.activateAntialiasing(g);
g.setColor(getBackground());
if (getIcon() != null)
{
if (isSecure)
g.fillRoundRect(
0, 0, this.getWidth(), this.getHeight(), 20, 20);
else
g.fillRoundRect(
0, 0, this.getWidth(), this.getHeight(), 20, 20);
}
g.setColor(getForeground());
super.paintComponent(g);
}
ImageIcon videoStatusIcon;
String videoStatusString;
if (isVideoSecurityOn)
finally
{
videoStatusIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_VIDEO_ON));
videoStatusString = "Video security on.";
g.dispose();
}
else
{
videoStatusIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_VIDEO_OFF));
videoStatusString = "Video security off.";
}
String cipher = "Cipher: " + encryptionCipher;
tip.addLine(audioStatusIcon,
audioStatusString);
tip.addLine(videoStatusIcon,
videoStatusString);
tip.addLine(null, cipher);
tip.setComponent(this);
return tip;
}
/**
* Gets the audio security status.
* @return the audio security status.
*/
public boolean isAudioSecurityOn()
{
return isAudioSecurityOn;
}
/**
* Sets the audio security on or off.
*
* @param isAudioSecurityOn indicates if the audio security is turned on or
* off.
*/
public void setAudioSecurityOn(boolean isAudioSecurityOn)
{
this.isAudioSecurityOn = isAudioSecurityOn;
}
/**
* Gets the video security status.
* @return the video security status.
*/
public boolean isVideoSecurityOn()
public void setSecurityOn()
{
return isVideoSecurityOn;
isSecure = true;
setIcon(securityOnIcon);
setBackground(securityOnBackground);
setToolTipText(GuiActivator.getResources().getI18NString(
"service.gui.security.CALL_SECURED_TOOLTIP"));
}
/**
* Sets the video security on or off.
*
* @param isVideoSecurityOn indicates if the video security is turned on or
* off.
* Sets the audio security on or off.
*/
public void setVideoSecurityOn(boolean isVideoSecurityOn)
public void setSecurityOff()
{
this.isVideoSecurityOn = isVideoSecurityOn;
isSecure = false;
setIcon(securityOffIcon);
setBackground(securityOffBackground);
this.setToolTipText(GuiActivator.getResources().getI18NString(
"service.gui.security.CALL_NOT_SECURED_TOOLTIP"));
}
/**
* Sets the cipher used for the encryption of the current call.
*
* @param encryptionCipher the cipher used for the encryption of the
* current call.
* Sets the audio security on or off.
*/
public void setEncryptionCipher(String encryptionCipher)
public void setSecurityPending()
{
this.encryptionCipher = encryptionCipher;
isSecure = false;
setIcon(securityOnIcon);
setBackground(goingSecureBackground);
this.setToolTipText(GuiActivator.getResources().getI18NString(
"service.gui.security.CALL_SECURED_COMPARE_TOOLTIP"));
}
/**
* Reloads icon.
* Reloads icons.
*/
public void loadSkin()
{
this.setIcon(defaultIcon);
securityOffIcon = new ImageIcon(ImageLoader
.getImage(ImageLoader.SECURE_BUTTON_OFF));
securityOnIcon = new ImageIcon(ImageLoader
.getImage(ImageLoader.SECURE_BUTTON_ON));
}
}

@ -8,12 +8,17 @@
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.media.*;
import net.java.sip.communicator.util.event.*;
import net.java.sip.communicator.util.swing.*;
/**
@ -24,102 +29,580 @@
* @author Yana Stamcheva
*/
public class ZrtpSecurityPanel
extends SecurityPanel
extends SecurityPanel<ZrtpControl>
implements VideoListener,
PropertyChangeListener
{
private SIPCommButton sasVerificationButton;
private Image iconEncr;
private Image iconEncrVerified;
private final JLabel securityStringLabel = new JLabel();
/**
* The icon indicating that the short authentication string has been
* verified.
*/
private static Icon encryptionVerifiedIcon;
/**
* The icon indicating that the audio is secure.
*/
private static Icon audioSecuredIcon;
/**
* The icon indicating that the audio is not secure.
*/
private static Icon audioNotSecuredIcon;
/**
* The icon indicating that the video is secure.
*/
private static Icon videoSecuredIcon;
/**
* The icon indicating that the video is not secure.
*/
private static Icon videoNotSecuredIcon;
/**
* The label showing the security authentication string.
*/
private final JLabel securityStringLabel = createSecurityLabel("", null);
/**
* The label showing audio security status.
*/
private final JLabel audioSecurityLabel;
/**
* The label showing video security status.
*/
private final JLabel videoSecurityLabel;
/**
* The button, which closes this panel.
*/
private final JButton closeButton
= new SIPCommButton(ImageLoader.getImage(ImageLoader.CLOSE_VIDEO));
/**
* The label containing information about the security authentication
* string.
*/
private final JLabel compareLabel = createSecurityLabel("", null);
/**
* The button confirming the security authentication string.
*/
private final JButton confirmButton = new JButton("");
/**
* The label showing the cipher.
*/
private JLabel cipherLabel;
/**
* Indicates if the security authentication string has been verified.
*/
private boolean sasVerified = false;
private final ZrtpControl zrtpControl;
/**
* Indicates the state of the audio security (on or off).
*/
private boolean isAudioSecurityOn = false;
/**
* Indicates the state of the video security (on or off).
*/
private boolean isVideoSecurityOn = false;
/**
* The encryption cipher.
*/
private String encryptionCipher;
/**
* The corresponding call peer.
*/
private final CallPeer callPeer;
/**
* The renderer of the corresponding call peer.
*/
private final CallPeerRenderer peerRenderer;
/**
* Creates an instance of <tt>SecurityPanel</tt> by specifying the
* corresponding <tt>peer</tt>.
*
*
* @param peerRenderer the parent renderer
* @param callPeer the peer, which security this panel is about
* @param zrtpControl the ZRTP security controller that provides information
* for this panel and receives the user input
*/
public ZrtpSecurityPanel(ZrtpControl zrtpControl)
public ZrtpSecurityPanel( CallPeerRenderer peerRenderer,
CallPeer callPeer,
ZrtpControl zrtpControl)
{
this.zrtpControl = zrtpControl;
super(zrtpControl);
this.setBorder(null);
this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 0));
this.peerRenderer = peerRenderer;
this.callPeer = callPeer;
this.setToolTipText(GuiActivator.getResources().getI18NString(
"service.gui.COMPARE_WITH_PARTNER"));
OperationSetVideoTelephony telephony
= callPeer.getProtocolProvider()
.getOperationSet(OperationSetVideoTelephony.class);
telephony.addVideoListener(callPeer, this);
telephony.addPropertyChangeListener(callPeer.getCall(), this);
audioSecurityLabel = createSecurityLabel("", null);
videoSecurityLabel = createSecurityLabel("", null);
loadSkin();
}
/**
* Adds security related components to this panel.
* Adds all components.
*/
private void addComponentsToPane()
private void addComponents()
{
this.add(sasVerificationButton);
this.add(securityStringLabel);
setAudioSecurityOn(isAudioSecurityOn);
setVideoSecurityOn(isVideoSecurityOn);
securityStringLabel
.setFont(securityStringLabel.getFont().deriveFont(14f));
closeButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
peerRenderer.setSecurityPanelVisible(false);
}
});
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
// Action to trigger SAS verification
sasVerificationButton.addActionListener(new ActionListener()
constraints.anchor = GridBagConstraints.NORTHEAST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridheight = 1;
constraints.weightx = 0f;
constraints.weighty = 0f;
this.add(audioSecurityLabel, constraints);
constraints.anchor = GridBagConstraints.NORTHEAST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridheight = 1;
constraints.weightx = 0f;
constraints.weighty = 0f;
constraints.insets = new Insets(5, 0, 0, 0);
this.add(videoSecurityLabel, constraints);
String cipher = "";
if (encryptionCipher != null && encryptionCipher.length() > 0)
{
cipher = GuiActivator.getResources().getI18NString(
"service.gui.CIPHER", new String[]{encryptionCipher});
}
cipherLabel = createSecurityLabel(cipher, null);
constraints.anchor = GridBagConstraints.NORTHEAST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 2;
constraints.gridheight = 1;
constraints.weightx = 0f;
constraints.weighty = 0f;
constraints.insets = new Insets(5, 0, 0, 0);
this.add(cipherLabel, constraints);
constraints.anchor = GridBagConstraints.NORTHWEST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 1;
constraints.gridy = 0;
constraints.gridheight = 3;
constraints.weightx = 1f;
constraints.weighty = 0f;
constraints.insets = new Insets(0, 5, 0, 5);
this.add(createSasPanel(), constraints);
constraints.anchor = GridBagConstraints.NORTHEAST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 0;
constraints.gridheight = 1;
constraints.weightx = 0f;
constraints.weighty = 0f;
constraints.insets = new Insets(0, 0, 0, 5);
this.add(closeButton, constraints);
}
/**
* Creates a security panel label.
*
* @param text the text of the label
* @param icon the label icon
* @return the created JLabel
*/
private JLabel createSecurityLabel(String text, Icon icon)
{
JLabel label = new JLabel(text, icon, JLabel.LEFT);
label.setForeground(Color.WHITE);
return label;
}
/**
* Creates the ZRTP sas panel.
*
* @return the created ZRTP SAS panel
*/
private JPanel createSasPanel()
{
sasVerified = getSecurityControl().isSecurityVerified();
TransparentPanel sasPanel = new TransparentPanel()
{
public void paintComponent(Graphics g)
{
g = g.create();
try
{
AntialiasingManager.activateAntialiasing(g);
g.setColor(new Color(1f, 1f, 1f, 0.1f));
g.fillRoundRect(
0, 0, this.getWidth(), this.getHeight(), 10, 10);
g.setColor(Color.WHITE);
g.drawRoundRect(
0, 0,
this.getWidth() - 1, this.getHeight() - 1,
10, 10);
}
finally
{
g.dispose();
}
}
};
sasPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
sasPanel.setPreferredSize(new Dimension(200, 80));
sasPanel.setMinimumSize(new Dimension(200, 80));
sasPanel.setMaximumSize(new Dimension(200, 80));
sasPanel.setLayout(new BoxLayout(sasPanel, BoxLayout.Y_AXIS));
initSasLabels();
SIPCommButton infoButton = new SIPCommButton(
ImageLoader.getImage(ImageLoader.CALL_INFO));
infoButton.setToolTipText(GuiActivator.getResources()
.getI18NString("service.gui.security.SAS_INFO_TOOLTIP"));
compareLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
JPanel stringPanel = new TransparentPanel(
new FlowLayout(FlowLayout.CENTER, 5, 0));
stringPanel.add(compareLabel);
stringPanel.add(infoButton);
sasPanel.add(stringPanel);
securityStringLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
sasPanel.add(securityStringLabel);
confirmButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
sasVerified = !sasVerified;
zrtpControl.setSASVerification(sasVerified);
if (getSecurityControl() != null)
{
getSecurityControl().setSASVerification(!sasVerified);
sasVerified = !sasVerified;
securityStringLabel
.setIcon(sasVerified ? encryptionVerifiedIcon : null);
if (sasVerified)
peerRenderer.securityOn(null);
else
peerRenderer.securityPending();
if (sasVerified)
sasVerificationButton.setImage(iconEncrVerified);
else
sasVerificationButton.setImage(iconEncr);
initSasLabels();
}
}
});
confirmButton.setAlignmentX(Component.CENTER_ALIGNMENT);
sasPanel.add(confirmButton);
return sasPanel;
}
/**
* Initializes security authentication string labels depending on the
* security verification status.
*/
private void initSasLabels()
{
if (!sasVerified)
{
compareLabel.setText(GuiActivator.getResources().getI18NString(
"service.gui.security.COMPARE_WITH_PARTNER_SHORT"));
confirmButton.setText(GuiActivator.getResources()
.getI18NString("servoce.gui.CONFIRM"));
}
else
{
compareLabel.setText(GuiActivator.getResources().getI18NString(
"service.gui.security.STRING_COMPARED"));
confirmButton.setText(GuiActivator.getResources()
.getI18NString("servoce.gui.CLEAR"));
}
if (compareLabel.isVisible())
{
compareLabel.revalidate();
compareLabel.repaint();
confirmButton.revalidate();
confirmButton.repaint();
}
}
/**
* Refreshes the state of the SAS and the SAS verified padlock.
*
* @param evt the security event of which we're notified
*/
public void refreshStates()
public void securityOn(CallPeerSecurityOnEvent evt)
{
String securityString = zrtpControl.getSecurityString();
encryptionCipher = evt.getCipher();
if (encryptionCipher != null)
cipherLabel.setText(GuiActivator.getResources().getI18NString(
"service.gui.security.CIPHER", new String[]{encryptionCipher}));
switch (evt.getSessionType())
{
case CallPeerSecurityStatusEvent.AUDIO_SESSION:
setAudioSecurityOn(true);
break;
case CallPeerSecurityStatusEvent.VIDEO_SESSION:
setVideoSecurityOn(true);
break;
}
String securityString = getSecurityControl().getSecurityString();
if (securityString != null)
{
securityStringLabel.setText(
GuiActivator.getResources().getI18NString(
"service.gui.COMPARE_WITH_PARTNER_SHORT",
new String[] {securityString}
)
);
securityStringLabel.setText(securityString);
}
else
{
securityStringLabel.setText(null);
}
sasVerified = zrtpControl.isSecurityVerified();
sasVerificationButton
.setImage(sasVerified ? iconEncrVerified : iconEncr);
sasVerified = getSecurityControl().isSecurityVerified();
securityStringLabel
.setIcon(sasVerified ? encryptionVerifiedIcon : null);
revalidate();
repaint();
}
/**
* Indicates that the security has gone off.
*/
public void securityOff(CallPeerSecurityOffEvent evt)
{
switch (evt.getSessionType())
{
case CallPeerSecurityStatusEvent.AUDIO_SESSION:
setAudioSecurityOn(false);
break;
case CallPeerSecurityStatusEvent.VIDEO_SESSION:
setVideoSecurityOn(false);
break;
}
revalidate();
repaint();
}
public void securityTimeout(CallPeerSecurityTimeoutEvent evt)
{
}
/**
* Reloads icons and components.
*/
public void loadSkin()
{
this.removeAll();
iconEncrVerified = ImageLoader.getImage(ImageLoader.ENCR_VERIFIED);
iconEncr = ImageLoader.getImage(ImageLoader.ENCR);
sasVerificationButton = new SIPCommButton(iconEncr);
removeAll();
encryptionVerifiedIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.ENCR_VERIFIED));
audioSecuredIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_AUDIO_ON));
audioNotSecuredIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_AUDIO_OFF));
videoSecuredIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_VIDEO_ON));
videoNotSecuredIcon = new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_VIDEO_OFF));
addComponents();
if (isVisible())
{
revalidate();
repaint();
}
}
/**
* Updates audio security related components, depending on the given audio
* security state.
*
* @param isAudioSecurityOn indicates if the audio is secured or not
*/
private void setAudioSecurityOn(final boolean isAudioSecurityOn)
{
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
setAudioSecurityOn(isAudioSecurityOn);
}
});
return;
}
Icon statusIcon;
String statusText;
this.isAudioSecurityOn = isAudioSecurityOn;
if (isAudioSecurityOn)
{
statusIcon = audioSecuredIcon;
statusText = GuiActivator.getResources()
.getI18NString("service.gui.security.SECURE_AUDIO");
}
else
{
statusIcon = audioNotSecuredIcon;
statusText = GuiActivator.getResources()
.getI18NString("service.gui.security.AUDIO_NOT_SECURED");
}
this.addComponentsToPane();
audioSecurityLabel.setIcon(statusIcon);
audioSecurityLabel.setText(statusText);
}
/**
* Updates video security related components, depending on the given video
* security state.
*
* @param isVideoSecurityOn indicates if the video is secured or not
*/
private void setVideoSecurityOn(final boolean isVideoSecurityOn)
{
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
setVideoSecurityOn(isVideoSecurityOn);
}
});
return;
}
this.isVideoSecurityOn = isVideoSecurityOn;
Icon statusIcon = null;
String statusText = null;
final OperationSetVideoTelephony telephony
= callPeer.getProtocolProvider()
.getOperationSet(OperationSetVideoTelephony.class);
if (telephony != null
&& ((telephony.getVisualComponents(callPeer) != null
&& telephony.getVisualComponents(callPeer).size() > 0)
|| ((MediaAwareCallPeer<?, ?, ?>) callPeer)
.isLocalVideoStreaming()))
{
if (isVideoSecurityOn)
{
statusIcon = videoSecuredIcon;
statusText = GuiActivator.getResources()
.getI18NString("service.gui.security.SECURE_VIDEO");
}
else
{
statusIcon = videoNotSecuredIcon;
statusText = GuiActivator.getResources()
.getI18NString("service.gui.security.VIDEO_NOT_SECURED");
}
}
else
{
videoSecurityLabel.setVisible(false);
}
if (statusIcon != null && statusText != null)
{
videoSecurityLabel.setIcon(statusIcon);
videoSecurityLabel.setText(statusText);
if (!videoSecurityLabel.isVisible())
videoSecurityLabel.setVisible(true);
}
revalidate();
repaint();
}
/**
* {@inheritDoc}
*/
public void propertyChange(final PropertyChangeEvent event)
{
if (OperationSetVideoTelephony.LOCAL_VIDEO_STREAMING
.equals(event.getPropertyName()))
{
setVideoSecurityOn(isAudioSecurityOn);
}
}
/**
* {@inheritDoc}
*/
public void videoAdded(VideoEvent event)
{
setVideoSecurityOn(isAudioSecurityOn);
}
/**
* {@inheritDoc}
*/
public void videoRemoved(VideoEvent event)
{
setVideoSecurityOn(isAudioSecurityOn);
}
/**
* {@inheritDoc}
*/
public void videoUpdate(VideoEvent event)
{
setVideoSecurityOn(isAudioSecurityOn);
}
}

@ -13,6 +13,7 @@
import net.java.sip.communicator.impl.gui.main.call.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
@ -161,10 +162,8 @@ public BasicConferenceParticipantPanel( CallRenderer renderer,
SoundLevelChangeEvent.MIN_LEVEL,
SoundLevelChangeEvent.MAX_LEVEL);
securityStatusLabel = new SecurityStatusLabel(
renderer.getCallContainer().getCallWindow().getFrame(),
new ImageIcon(
ImageLoader.getImage(ImageLoader.SECURE_OFF_CONF_CALL)));
securityStatusLabel = new SecurityStatusLabel();
securityStatusLabel.setSecurityOff();
this.setLayout(new GridBagLayout());
this.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7));
@ -270,6 +269,8 @@ public void addToStatusBar(Component component)
{
statusBarConstraints.gridx = statusBarConstraints.gridx + 1;
statusBarConstraints.weightx = 0f;
statusBarConstraints.insets = new Insets(0, 5, 0, 5);
this.statusBar.add(component, statusBarConstraints);
}
@ -439,25 +440,32 @@ public void loadSkin()
*/
public void securityOn(CallPeerSecurityOnEvent evt)
{
if ((evt.getSecurityController().requiresSecureSignalingTransport()
&& renderer.getCall().getProtocolProvider()
.isSignalingTransportSecure())
|| !evt.getSecurityController().requiresSecureSignalingTransport())
// If the securityOn is called without a specific event, we'll just set
// the security label status to on.
if (evt == null)
{
securityImageID = ImageLoader.SECURE_ON_CONF_CALL;
securityStatusLabel.setIcon(new ImageIcon(ImageLoader
.getImage(securityImageID)));
securityStatusLabel.setSecurityOn();
return;
}
securityStatusLabel.setEncryptionCipher(evt.getCipher());
switch (evt.getSessionType())
SrtpControl srtpControl = evt.getSecurityController();
if ((srtpControl.requiresSecureSignalingTransport()
&& renderer.getCall().getProtocolProvider()
.isSignalingTransportSecure())
|| !srtpControl.requiresSecureSignalingTransport())
{
case CallPeerSecurityStatusEvent.AUDIO_SESSION:
securityStatusLabel.setAudioSecurityOn(true);
break;
case CallPeerSecurityStatusEvent.VIDEO_SESSION:
securityStatusLabel.setVideoSecurityOn(true);
break;
if (srtpControl instanceof ZrtpControl)
{
securityStatusLabel.setText("zrtp");
if (!((ZrtpControl) srtpControl).isSecurityVerified())
securityStatusLabel.setSecurityPending();
else
securityStatusLabel.setSecurityOn();
}
else
securityStatusLabel.setSecurityOn();
}
}
@ -468,19 +476,18 @@ public void securityOn(CallPeerSecurityOnEvent evt)
*/
public void securityOff(CallPeerSecurityOffEvent evt)
{
securityImageID = ImageLoader.SECURE_OFF_CONF_CALL;
securityStatusLabel.setIcon(new ImageIcon(ImageLoader
.getImage(securityImageID)));
securityStatusLabel.setText("");
securityStatusLabel.setSecurityOff();
if (securityStatusLabel.getBorder() == null)
securityStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 5, 2, 3));
}
securityStatusLabel.setEncryptionCipher(null);
switch (evt.getSessionType())
{
case CallPeerSecurityStatusEvent.AUDIO_SESSION:
securityStatusLabel.setAudioSecurityOn(false);
break;
case CallPeerSecurityStatusEvent.VIDEO_SESSION:
securityStatusLabel.setVideoSecurityOn(false);
break;
}
/**
* Indicates that the security status is pending confirmation.
*/
public void securityPending()
{
securityStatusLabel.setSecurityPending();
}
}

@ -276,9 +276,9 @@ public void setPeerImage(byte[] image)
*
* @param state the state of the contained call peer
*/
public void setPeerState(String state)
public void setPeerState(CallPeerState peerState, String state)
{
focusPeerPanel.setPeerState(state);
focusPeerPanel.setPeerState(peerState, state);
}
/**
@ -321,6 +321,7 @@ public void setOnHold(boolean isOnHold)
public void securityOn(CallPeerSecurityOnEvent evt)
{
focusPeerPanel.securityOn(evt);
for (ConferenceMemberPanel member : conferenceMembersPanels.values())
{
member.securityOn(evt);
@ -341,6 +342,14 @@ public void securityOff(CallPeerSecurityOffEvent evt)
}
}
/**
* Indicates that the security status is pending confirmation.
*/
public void securityPending()
{
focusPeerPanel.securityPending();
}
/**
* Indicates that the security is timeouted, is not supported by the
* other end.
@ -646,4 +655,15 @@ public void soundLevelChanged(
}
}
}
/**
* Shows/hides the security panel.
*
* @param isVisible <tt>true</tt> to show the security panel, <tt>false</tt>
* to hide it
*/
public void setSecurityPanelVisible(boolean isVisible)
{
}
}

@ -7,6 +7,7 @@
package net.java.sip.communicator.impl.gui.main.call.conference;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@ -15,6 +16,7 @@
import net.java.sip.communicator.impl.gui.main.call.CallPeerAdapter; // disambiguation
import net.java.sip.communicator.impl.gui.main.presence.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.skin.*;
@ -153,6 +155,8 @@ public ConferencePeerPanel( ConferenceCallPanel callRenderer,
this.callPeer = callPeer;
this.videoHandler = videoHandler;
this.securityPanel = SecurityPanel.create(this, callPeer, null);
this.setMute(callPeer.isMute());
this.setPeerImage(CallManager.getPeerImage(callPeer));
@ -192,6 +196,23 @@ private void initSecuritySettings()
securityOn(securityOnEvt);
}
securityStatusLabel.setBorder(
BorderFactory.createEmptyBorder(2, 5, 2, 5));
securityStatusLabel.setSecurityOff();
securityStatusLabel.addMouseListener(new MouseAdapter()
{
/**
* Invoked when a mouse button has been pressed on a component.
*/
public void mousePressed(MouseEvent e)
{
setSecurityPanelVisible(!callRenderer.getCallContainer()
.getCallWindow().getFrame().getGlassPane().isVisible());
}
});
}
/**
@ -207,13 +228,33 @@ public void securityOn(CallPeerSecurityOnEvent evt)
{
super.securityOn(evt);
// If the securityOn is called without a specific event, we'll just call
// the super and we'll return.
if (evt == null)
return;
SrtpControl srtpControl = evt.getSecurityController();
// In case this is the local peer.
if (securityPanel == null)
return;
// if we have some other panel, using other control
if (securityPanel.getSecurityControl() == null
|| !srtpControl.getClass().isInstance(
securityPanel.getSecurityControl()))
{
securityPanel = SecurityPanel.create(evt.getSecurityController());
securityPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
this.addToCenter(securityPanel);
setSecurityPanelVisible(false);
securityPanel
= SecurityPanel.create(this, callPeer, srtpControl);
}
securityPanel.refreshStates();
securityPanel.securityOn(evt);
if (srtpControl instanceof ZrtpControl
&& !((ZrtpControl) srtpControl).isSecurityVerified())
setSecurityPanelVisible(true);
callPanel.refreshContainer();
}
@ -227,15 +268,21 @@ public void securityOn(CallPeerSecurityOnEvent evt)
public void securityOff(CallPeerSecurityOffEvent evt)
{
super.securityOff(evt);
if(securityPanel != null
&& !securityStatusLabel.isAudioSecurityOn()
&& !securityStatusLabel.isVideoSecurityOn())
if(securityPanel != null)
{
securityPanel.getParent().remove(securityPanel);
securityPanel = null;
securityPanel.securityOff(evt);
}
}
/**
* Indicates that the security status is pending confirmation.
*/
public void securityPending()
{
super.securityPending();
}
/**
* Indicates that the security is timeouted, is not supported by the
* other end.
@ -306,7 +353,7 @@ public void setPeerName(String name)
*
* @param state the state of the contained call peer
*/
public void setPeerState(String state)
public void setPeerState(CallPeerState peerState, String state)
{
this.setParticipantState(state);
}
@ -497,4 +544,146 @@ public String getCallPeerContactAddress()
{
return callPeer.getURI();
}
/**
* Shows/hides the security panel.
*
* @param isVisible <tt>true</tt> to show the security panel, <tt>false</tt>
* to hide it
*/
public void setSecurityPanelVisible(boolean isVisible)
{
final JFrame callFrame = callRenderer.getCallContainer()
.getCallWindow().getFrame();
final JPanel glassPane = (JPanel) callFrame.getGlassPane();
if (!isVisible)
{
// Need to hide the security panel explicitly in order to keep the
// fade effect.
securityPanel.setVisible(false);
glassPane.setVisible(false);
glassPane.removeAll();
}
else
{
glassPane.setLayout(null);
glassPane.addMouseListener(new MouseListener()
{
public void mouseReleased(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mousePressed(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mouseExited(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mouseEntered(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
public void mouseClicked(MouseEvent e)
{
redispatchMouseEvent(glassPane, e);
}
});
Point securityLabelPoint = securityStatusLabel.getLocation();
Point newPoint
= SwingUtilities.convertPoint(securityStatusLabel.getParent(),
securityLabelPoint.x, securityLabelPoint.y,
callFrame);
securityPanel.setBeginPoint(
new Point((int) newPoint.getX() + 15, 0));
securityPanel.setBounds(
0, (int) newPoint.getY() - 5, callFrame.getWidth(), 110);
glassPane.add(securityPanel);
// Need to show the security panel explicitly in order to keep the
// fade effect.
securityPanel.setVisible(true);
glassPane.setVisible(true);
glassPane.addComponentListener(new ComponentAdapter()
{
/**
* Invoked when the component's size changes.
*/
public void componentResized(ComponentEvent e)
{
if (glassPane.isVisible())
{
glassPane.setVisible(false);
callFrame.removeComponentListener(this);
}
}
});
}
}
/**
* Re-dispatches glass pane mouse events only in case they occur on the
* security panel.
*
* @param glassPane the glass pane
* @param e the mouse event in question
*/
private void redispatchMouseEvent(Component glassPane, MouseEvent e)
{
Point glassPanePoint = e.getPoint();
Point securityPanelPoint = SwingUtilities.convertPoint(
glassPane,
glassPanePoint,
securityPanel);
Component component;
Point componentPoint;
if (securityPanelPoint.y > 0)
{
component = securityPanel;
componentPoint = securityPanelPoint;
}
else
{
Container contentPane
= callRenderer.getCallContainer().getCallWindow()
.getFrame().getContentPane();
Point containerPoint = SwingUtilities.convertPoint(
glassPane,
glassPanePoint,
contentPane);
component = SwingUtilities.getDeepestComponentAt(contentPane,
containerPoint.x, containerPoint.y);
componentPoint = SwingUtilities.convertPoint(contentPane,
glassPanePoint, component);
}
if (component != null)
component.dispatchEvent(new MouseEvent( component,
e.getID(),
e.getWhen(),
e.getModifiers(),
componentPoint.x,
componentPoint.y,
e.getClickCount(),
e.isPopupTrigger()));
e.consume();
}
}

@ -0,0 +1,190 @@
/*
* 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.util.swing;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import org.jvnet.lafwidget.animation.*;
/**
* The <tt>FadeInBaloonPanel</tt> is a semi-transparent "balloon" panel, which
* could be shown in a glass pane for example. You can define a begin point,
* where the balloon triangle would show.
*
* @author Yana Stamcheva
*/
public class FadeInBalloonPanel
extends TransparentPanel
{
/**
* The begin point, where the balloon triangle will be shown.
*/
private Point beginPoint;
/**
* The begin point shift, which defines the rectangle point shift.
*/
private final static int beginPointShift = 6;
/**
* Sets the begin point.
*
* @param beginPoint the begin point
*/
public void setBeginPoint(Point beginPoint)
{
this.beginPoint = beginPoint;
}
/**
* Overrides the <code>paintComponent</code> method of <tt>JButton</tt> to
* paint the button background and icon, and all additional effects of this
* configurable button.
*
* @param g The Graphics object.
*/
protected void paintComponent(Graphics g)
{
g = g.create();
try
{
internalPaintComponent((Graphics2D) g);
}
finally
{
g.dispose();
}
}
/**
* Paints this button.
* @param g the <tt>Graphics</tt> object used for painting
*/
private void internalPaintComponent(Graphics2D g)
{
AntialiasingManager.activateAntialiasing(g);
/*
* As JComponent#paintComponent says, if you do not invoke super's
* implementation you must honor the opaque property, that is if this
* component is opaque, you must completely fill in the background in a
* non-opaque color. If you do not honor the opaque property you will
* likely see visual artifacts.
*/
if (isOpaque())
{
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
// Paint a roll over fade out.
FadeTracker fadeTracker = FadeTracker.getInstance();
float visibility = isVisible() ? 0.8f : 0.0f;
if (fadeTracker.isTracked(this, FadeKind.ROLLOVER))
{
visibility = fadeTracker.getFade(this, FadeKind.ROLLOVER);
}
g.setColor(new Color(0f, 0f, 0f, visibility));
int y = 0;
// draw triangle (polygon)
if (beginPoint != null)
{
y = beginPointShift;
int x1Points[] = { beginPoint.x,
beginPoint.x + beginPointShift,
beginPoint.x - beginPointShift};
int y1Points[] = { beginPoint.y,
beginPoint.y + beginPointShift,
beginPoint.y + beginPointShift};
GeneralPath polygon =
new GeneralPath(GeneralPath.WIND_EVEN_ODD,
x1Points.length);
polygon.moveTo(x1Points[0], y1Points[0]);
for (int index = 1; index < x1Points.length; index++) {
polygon.lineTo(x1Points[index], y1Points[index]);
};
polygon.closePath();
g.fill(polygon);
}
if (visibility != 0.0f)
{
g.fillRoundRect(
0, y, this.getWidth(), this.getHeight(), 10, 10);
}
}
/**
* The <tt>ButtonRepaintCallback</tt> is charged to repaint this button
* when the fade animation is performed.
*/
private class PanelRepaintCallback implements FadeTrackerCallback
{
public void fadeEnded(FadeKind arg0)
{
repaintLater();
}
public void fadePerformed(FadeKind arg0, float arg1)
{
repaintLater();
}
private void repaintLater()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
FadeInBalloonPanel.this.repaint();
}
});
}
public void fadeReversed(FadeKind arg0, boolean arg1, float arg2)
{
}
}
/**
* Shows/hides this panel.
*
* @param isVisible <tt>true</tt> to show this panel, <tt>false</tt> to
* hide it
*/
public void setVisible(boolean isVisible)
{
FadeTracker fadeTracker = FadeTracker.getInstance();
if (isVisible)
{
fadeTracker.trackFadeIn(FadeKind.ROLLOVER,
FadeInBalloonPanel.this,
true,
new PanelRepaintCallback());
}
else
{
fadeTracker.trackFadeOut(FadeKind.ROLLOVER,
FadeInBalloonPanel.this,
true,
new PanelRepaintCallback());
}
}
}

@ -300,7 +300,7 @@ protected Rectangle getVisibleEditorRect()
}
JTextComponent c = getComponent();
if(c == null)
return null;

Loading…
Cancel
Save