/** * Place to put some hacks if needed on incoming requests. * * @param event the incoming request event. * @return status <code>true</code> if we don't need to process this message, just discard it and * <code>false</code> otherwise. */ private boolean applyNonConformanceHacks(RequestEvent event) { Request request = event.getRequest(); try { /* * Max-Forwards is required, yet there are UAs which do not * place it. SipProvider#getNewServerTransaction(Request) * will throw an exception in the case of a missing * Max-Forwards header and this method will eventually just * log it thus ignoring the whole event. */ if (request.getHeader(MaxForwardsHeader.NAME) == null) { // it appears that some buggy providers do send requests // with no Max-Forwards headers, as we are at application level // and we know there will be no endless loops // there is no problem of adding headers and process normally // this messages MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); request.setHeader(maxForwards); } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } try { // using asterisk voice mail initial notify for messages // is ok, but on the fly received messages their notify comes // without subscription-state, so we add it in order to be able to // process message. if (request.getMethod().equals(Request.NOTIFY) && request.getHeader(EventHeader.NAME) != null && ((EventHeader) request.getHeader(EventHeader.NAME)) .getEventType() .equals(OperationSetMessageWaitingSipImpl.EVENT_PACKAGE) && request.getHeader(SubscriptionStateHeader.NAME) == null) { request.addHeader( new HeaderFactoryImpl().createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE)); } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } try { // receiving notify message without subscription state // used for keep-alive pings, they have done their job // and are no more need. Skip processing them to avoid // filling logs with unneeded exceptions. if (request.getMethod().equals(Request.NOTIFY) && request.getHeader(SubscriptionStateHeader.NAME) == null) { return true; } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } return false; }
/** * Receives options requests and replies with an OK response containing methods that we support. * * @param requestEvent the incoming options request. * @return <tt>true</tt> if request has been successfully processed, <tt>false</tt> otherwise */ @Override public boolean processRequest(RequestEvent requestEvent) { Response optionsOK = null; try { optionsOK = provider.getMessageFactory().createResponse(Response.OK, requestEvent.getRequest()); // add to the allows header all methods that we support for (String method : provider.getSupportedMethods()) { // don't support REGISTERs if (!method.equals(Request.REGISTER)) optionsOK.addHeader(provider.getHeaderFactory().createAllowHeader(method)); } Iterable<String> knownEventsList = provider.getKnownEventsList(); synchronized (knownEventsList) { for (String event : knownEventsList) optionsOK.addHeader(provider.getHeaderFactory().createAllowEventsHeader(event)); } } catch (ParseException ex) { // What else could we do apart from logging? logger.warn("Failed to create an incoming OPTIONS request", ex); return false; } try { SipStackSharing.getOrCreateServerTransaction(requestEvent).sendResponse(optionsOK); } catch (TransactionUnavailableException ex) { // this means that we received an OPTIONS request outside the scope // of a transaction which could mean that someone is simply sending // us b****hit to keep a NAT connection alive, so let's not get too // excited. if (logger.isInfoEnabled()) logger.info("Failed to respond to an incoming " + "transactionless OPTIONS request"); if (logger.isTraceEnabled()) logger.trace("Exception was:", ex); return false; } catch (InvalidArgumentException ex) { // What else could we do apart from logging? logger.warn("Failed to send an incoming OPTIONS request", ex); return false; } catch (SipException ex) { // What else could we do apart from logging? logger.warn("Failed to send an incoming OPTIONS request", ex); return false; } return true; }
/** * Returns the <tt>URL</tt> of the sound corresponding to the given property key. * * @return the <tt>URL</tt> of the sound corresponding to the given property key. */ public URL getSoundURL(String urlKey) { String path = getSoundPath(urlKey); if (path == null || path.length() == 0) { logger.warn("Missing resource for key: " + urlKey); return null; } return getSoundURLForPath(path); }
/** * Process candidates received. * * @param sessionInitIQ The {@link SessionIQ} that created the session we are handling here */ public void processCandidates(SessionIQ sessionInitIQ) { Collection<PacketExtension> extensions = sessionInitIQ.getExtensions(); List<GTalkCandidatePacketExtension> candidates = new ArrayList<GTalkCandidatePacketExtension>(); for (PacketExtension ext : extensions) { if (ext.getElementName().equalsIgnoreCase(GTalkCandidatePacketExtension.ELEMENT_NAME)) { GTalkCandidatePacketExtension cand = (GTalkCandidatePacketExtension) ext; candidates.add(cand); } } try { getMediaHandler().processCandidates(candidates); } catch (OperationFailedException ofe) { logger.warn("Failed to process an incoming candidates", ofe); // send an error response String reasonText = "Error: " + ofe.getMessage(); SessionIQ errResp = GTalkPacketFactory.createSessionTerminate( sessionInitIQ.getTo(), sessionInitIQ.getFrom(), sessionInitIQ.getID(), Reason.GENERAL_ERROR, reasonText); getMediaHandler().getTransportManager().close(); setState(CallPeerState.FAILED, reasonText); getProtocolProvider().getConnection().sendPacket(errResp); return; } // HACK for FreeSwitch that send accept message before sending // candidates if (sessAcceptedWithNoCands != null) { if (isInitiator()) { try { answer(); } catch (OperationFailedException e) { logger.info("Failed to answer call (FreeSwitch hack)"); } } else { final SessionIQ sess = sessAcceptedWithNoCands; sessAcceptedWithNoCands = null; // run in another thread to not block smack receive thread and // possibly delay others candidates messages. new Thread() { @Override public void run() { processSessionAccept(sess); } }.start(); } sessAcceptedWithNoCands = null; } }
/** * Returns the <tt>InputStream</tt> of the image corresponding to the given key. * * @param streamKey The identifier of the image in the resource properties file. * @return the <tt>InputStream</tt> of the image corresponding to the given key. */ public InputStream getImageInputStream(String streamKey) { String path = getImagePath(streamKey); if (path == null || path.length() == 0) { logger.warn("Missing resource for key: " + streamKey); return null; } return getImageInputStreamForPath(path); }
/** * Checks whether the carbon is supported by the server or not. * * @return <tt>true</tt> if carbon is supported by the server and <tt>false</tt> if not. */ private boolean isCarbonSupported() { try { return jabberProvider .getDiscoveryManager() .discoverInfo(jabberProvider.getAccountID().getService()) .containsFeature(CarbonPacketExtension.NAMESPACE); } catch (XMPPException e) { logger.warn("Failed to retrieve carbon support." + e.getMessage()); } return false; }
/** * Sets the priority of the calling thread to a specific value. * * @param threadPriority the priority to be set on the calling thread */ public static void setThreadPriority(int threadPriority) { Throwable exception = null; try { Process.setThreadPriority(threadPriority); } catch (IllegalArgumentException iae) { exception = iae; } catch (SecurityException se) { exception = se; } if (exception != null) logger.warn("Failed to set thread priority.", exception); }
/** * Creates an account for the given user and password. * * @param providerFactory the ProtocolProviderFactory which will create the account * @param user the user identifier * @return the <tt>ProtocolProviderService</tt> for the new account. */ public ProtocolProviderService installAccount( ProtocolProviderFactory providerFactory, String user) throws OperationFailedException { Hashtable<String, String> accountProperties = new Hashtable<String, String>(); accountProperties.put( ProtocolProviderFactory.ACCOUNT_ICON_PATH, "resources/images/protocol/gibberish/gibberish32x32.png"); if (registration.isRememberPassword()) { accountProperties.put(ProtocolProviderFactory.PASSWORD, registration.getPassword()); } if (isModification()) { providerFactory.uninstallAccount(protocolProvider.getAccountID()); this.protocolProvider = null; setModification(false); } try { AccountID accountID = providerFactory.installAccount(user, accountProperties); ServiceReference serRef = providerFactory.getProviderForAccount(accountID); protocolProvider = (ProtocolProviderService) GibberishAccRegWizzActivator.bundleContext.getService(serRef); } catch (IllegalStateException exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Account already exists.", OperationFailedException.IDENTIFICATION_CONFLICT); } catch (Exception exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Failed to add account", OperationFailedException.GENERAL_ERROR); } return protocolProvider; }
/** * Creates an account for the given Account ID, Identity File and Known Hosts File * * @param providerFactory the ProtocolProviderFactory which will create the account * @param user the user identifier * @return the <tt>ProtocolProviderService</tt> for the new account. */ public ProtocolProviderService installAccount( ProtocolProviderFactory providerFactory, String user) throws OperationFailedException { Hashtable<String, String> accountProperties = new Hashtable<String, String>(); accountProperties.put( ProtocolProviderFactory.ACCOUNT_ICON_PATH, "resources/images/protocol/ssh/ssh32x32.png"); accountProperties.put( ProtocolProviderFactory.NO_PASSWORD_REQUIRED, new Boolean(true).toString()); accountProperties.put( ProtocolProviderFactorySSHImpl.IDENTITY_FILE, registration.getIdentityFile()); accountProperties.put( ProtocolProviderFactorySSHImpl.KNOWN_HOSTS_FILE, String.valueOf(registration.getKnownHostsFile())); try { AccountID accountID = providerFactory.installAccount(user, accountProperties); ServiceReference serRef = providerFactory.getProviderForAccount(accountID); protocolProvider = (ProtocolProviderService) SSHAccRegWizzActivator.bundleContext.getService(serRef); } catch (IllegalStateException exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Account already exists.", OperationFailedException.IDENTIFICATION_CONFLICT); } catch (Exception exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Failed to add account", OperationFailedException.GENERAL_ERROR); } return protocolProvider; }
/** * Checks if there is a call in progress. If true then shows a warning toast and finishes the * activity. * * @param activity activity doing a check. * @return <tt>true</tt> if there is call in progress and <tt>Activity</tt> was finished. */ public static boolean checkCallInProgress(Activity activity) { if (CallManager.getActiveCallsCount() > 0) { logger.warn("Call is in progress"); Toast t = Toast.makeText(activity, R.string.service_gui_WARN_CALL_IN_PROGRESS, Toast.LENGTH_SHORT); t.show(); activity.finish(); return true; } else { return false; } }
/** * Retrieves default values from xml. * * @param list the configuration list */ private static void parseDefaults(NodeList list) { for (int i = 0; i < list.getLength(); ++i) { NamedNodeMap mapping = list.item(i).getAttributes(); String attribute = mapping.getNamedItem("attribute").getNodeValue(); String value = mapping.getNamedItem("value").getNodeValue(); try { Default field = Default.fromString(attribute); DEFAULTS.put(field, value); } catch (IllegalArgumentException exc) { logger.warn("Unrecognized default attribute: " + attribute); } } }
/** * Creates new call to given <tt>destination</tt> using selected <tt>provider</tt>. * * @param context the android context * @param destination target callee name. * @param provider the provider that will be used to make a call. */ public static void createCall( final Context context, final String destination, final ProtocolProviderService provider) { if (createCallThread != null) { logger.warn("Another call is already being created"); return; } else if (CallManager.getActiveCallsCount() > 0) { logger.warn("Another call is in progress"); return; } final long dialogId = ProgressDialogFragment.showProgressDialog( JitsiApplication.getResString(R.string.service_gui_OUTGOING_CALL), JitsiApplication.getResString(R.string.service_gui_OUTGOING_CALL_MSG, destination)); createCallThread = new Thread("Create call thread") { public void run() { try { CallManager.createCall(provider, destination); } catch (Throwable t) { logger.error("Error creating the call: " + t.getMessage(), t); AndroidUtils.showAlertDialog( context, context.getString(R.string.service_gui_ERROR), t.getMessage()); } finally { if (DialogActivity.waitForDialogOpened(dialogId)) { DialogActivity.closeDialog(JitsiApplication.getGlobalContext(), dialogId); } else { logger.error("Failed to wait for the dialog: " + dialogId); } createCallThread = null; } } }; createCallThread.start(); }
/** * Populates LOCALES list with contents of xml. * * @param list the configuration list */ private static void parseLocales(NodeList list) { for (int i = 0; i < list.getLength(); ++i) { Node node = list.item(i); NamedNodeMap attributes = node.getAttributes(); String label = ((Attr) attributes.getNamedItem("label")).getValue(); String code = ((Attr) attributes.getNamedItem("isoCode")).getValue(); String dictLocation = ((Attr) attributes.getNamedItem("dictionaryUrl")).getValue(); try { LOCALES.add(new Locale(label, code, new URL(dictLocation))); } catch (MalformedURLException exc) { logger.warn( "Unable to parse dictionary location of " + label + " (" + dictLocation + ")", exc); } } }
static { try { URL url = SpellCheckActivator.bundleContext.getBundle().getResource(RESOURCE_LOC); InputStream stream = url.openStream(); if (stream == null) throw new IOException(); // strict parsing options DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); // parses configuration xml /*- * Warning: Felix is unable to import the com.sun.rowset.internal * package, meaning this can't use the XmlErrorHandler. This causes * a warning and a default handler to be attached. Otherwise this * should have: builder.setErrorHandler(new XmlErrorHandler()); */ DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(stream); // iterates over nodes, parsing contents Node root = doc.getChildNodes().item(1); NodeList categories = root.getChildNodes(); for (int i = 0; i < categories.getLength(); ++i) { Node node = categories.item(i); if (node.getNodeName().equals(NODE_DEFAULTS)) { parseDefaults(node.getChildNodes()); } else if (node.getNodeName().equals(NODE_LOCALES)) { parseLocales(node.getChildNodes()); } else { logger.warn("Unrecognized category: " + node.getNodeName()); } } } catch (IOException exc) { logger.error("Unable to load spell checker parameters", exc); } catch (SAXException exc) { logger.error("Unable to parse spell checker parameters", exc); } catch (ParserConfigurationException exc) { logger.error("Unable to parse spell checker parameters", exc); } }
/** * Function called when a icq file transfer request arrive * * @param manager the joustsim manager * @param transfer the incoming transfer */ public void handleNewIncomingConnection( RvConnectionManager manager, IncomingRvConnection transfer) { if (transfer instanceof IncomingFileTransfer) { if (logger.isTraceEnabled()) logger.trace("Incoming Icq file transfer request " + transfer.getClass()); if (!(transfer instanceof IncomingFileTransfer)) { logger.warn("Wrong file transfer."); return; } OperationSetPersistentPresenceIcqImpl opSetPersPresence = (OperationSetPersistentPresenceIcqImpl) icqProvider.getOperationSet(OperationSetPersistentPresence.class); Contact sender = opSetPersPresence.findContactByID(transfer.getBuddyScreenname().getFormatted()); IncomingFileTransfer incomingFileTransfer = (IncomingFileTransfer) transfer; final Date newDate = new Date(); final IncomingFileTransferRequest req = new IncomingFileTransferRequestIcqImpl( icqProvider, this, incomingFileTransfer, sender, newDate); // this handels when we receive request and before accept or decline // it we receive cancel transfer.addEventListener( new RvConnectionEventListener() { public void handleEventWithStateChange( RvConnection transfer, RvConnectionState state, RvConnectionEvent event) { if (state == FileTransferState.FAILED && event instanceof BuddyCancelledEvent) { fireFileTransferRequestCanceled( new FileTransferRequestEvent( OperationSetFileTransferIcqImpl.this, req, newDate)); } } public void handleEvent(RvConnection arg0, RvConnectionEvent arg1) {} }); fireFileTransferRequest(new FileTransferRequestEvent(this, req, newDate)); } }
/** * Returns an InetAddress instance that represents the localhost, and that a socket can bind upon * or distribute to peers as a contact address. * * @param intendedDestination the destination that we'd like to use the localhost address with. * @return an InetAddress instance representing the local host, and that a socket can bind upon or * distribute to peers as a contact address. */ public synchronized InetAddress getLocalHost(InetAddress intendedDestination) { // no point in making sure that the localHostFinderSocket is initialized. // better let it through a NullPointerException. InetAddress localHost = null; localHostFinderSocket.connect(intendedDestination, this.RANDOM_ADDR_DISC_PORT); localHost = localHostFinderSocket.getLocalAddress(); localHostFinderSocket.disconnect(); // windows socket implementations return the any address so we need to // find something else here ... InetAddress.getLocalHost seems to work // better on windows so lets hope it'll do the trick. if (localHost.isAnyLocalAddress()) { try { // all that's inside the if is an ugly IPv6 hack // (good ol' IPv6 - always causing more problems than it solves.) if (intendedDestination instanceof Inet6Address) { // return the first globally routable ipv6 address we find // on the machine (and hope it's a good one) Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface iface = (NetworkInterface) interfaces.nextElement(); Enumeration addresses = iface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = (InetAddress) addresses.nextElement(); if (address instanceof Inet6Address) { if (!address.isAnyLocalAddress() && !address.isLinkLocalAddress() && !address.isSiteLocalAddress() && !address.isLoopbackAddress()) { return address; } } } } } else localHost = InetAddress.getLocalHost(); /** @todo test on windows for ipv6 cases */ } catch (Exception ex) { // sigh ... ok return 0.0.0.0 logger.warn("Failed to get localhost ", ex); } } return localHost; }
/** * Dispatches the event received from a JAIN-SIP <tt>SipProvider</tt> to one of our "candidate * recipient" listeners. * * @param event the event received for a <tt>SipProvider</tt>. */ public void processResponse(ResponseEvent event) { try { // we don't have to accept the transaction since we // created the request ClientTransaction transaction = event.getClientTransaction(); if (logger.isTraceEnabled()) logger.trace( "received response: " + event.getResponse().getStatusCode() + " " + event.getResponse().getReasonPhrase()); if (transaction == null) { logger.warn("Transaction is null, probably already expired!"); return; } ProtocolProviderServiceSipImpl service = getServiceData(transaction); if (service != null) { // Mark the dialog for the dispatching of later in-dialog // responses. If there is no dialog then the initial request // sure is marked otherwise we won't have found the service with // getServiceData(). The request has to be marked in case we // receive one more response in an out-of-dialog transaction. if (event.getDialog() != null) { SipApplicationData.setApplicationData( event.getDialog(), SipApplicationData.KEY_SERVICE, service); } service.processResponse(event); } else { logger.error( "We received a response which " + "wasn't marked, please report this to " + "*****@*****.**"); } } catch (Throwable exc) { // any exception thrown within our code should be caught here // so that we could log it rather than interrupt stack activity with // it. this.logApplicationException(DialogTerminatedEvent.class, exc); } }
/** Handles XEP-0337 "log" extensions. */ private void handleLogRequest(LogPacketExtension log, String jid) { JitsiMeetConference conference = getConferenceForMucJid(jid); if (conference == null) { logger.debug("Room not found for JID: " + jid); return; } Participant participant = conference.findParticipantForRoomJid(jid); if (participant == null) { logger.info("Ignoring log request from an unknown JID: " + jid); return; } EventAdmin eventAdmin = FocusBundleActivator.getEventAdmin(); if (eventAdmin == null) return; if (LogUtil.LOG_ID_PC_STATS.equals(log.getID())) { String content = LogUtil.getContent(log); if (content != null) { ColibriConference colibriConference = conference.getColibriConference(); if (colibriConference != null) { Event event = EventFactory.peerConnectionStats( colibriConference.getConferenceId(), participant.getEndpointId(), content); if (event != null) eventAdmin.sendEvent(event); } else { logger.warn("Unhandled log request" + " - no valid Colibri conference"); } } } else if (logger.isInfoEnabled()) { logger.info("Ignoring log request with an unknown ID:" + log.getID()); } }
/** * Log a warning message. * * @param string the warning that we'd like to log */ public void logWarning(String string) { logger.warn("Warning from the JAIN-SIP stack" + string); }
/** * Gathers Jingle Nodes candidates for all host <tt>Candidate</tt>s that are already present in * the specified <tt>component</tt>. This method relies on the specified <tt>component</tt> to * already contain all its host candidates so that it would resolve them. * * @param component the {@link Component} that we'd like to gather candidate Jingle Nodes * <tt>Candidate</tt>s for * @return the <tt>LocalCandidate</tt>s gathered by this <tt>CandidateHarvester</tt> */ @Override public synchronized Collection<LocalCandidate> harvest(Component component) { logger.info("harvest Jingle Nodes"); Collection<LocalCandidate> candidates = new HashSet<LocalCandidate>(); String ip = null; int port = -1; /* if we have already a candidate (RTCP) allocated, get it */ if (localAddressSecond != null && relayedAddressSecond != null) { LocalCandidate candidate = createJingleNodesCandidate(relayedAddressSecond, component, localAddressSecond); // try to add the candidate to the component and then only add it to // the harvest not redundant (not sure how it could be red. but ...) if (component.addLocalCandidate(candidate)) { candidates.add(candidate); } localAddressSecond = null; relayedAddressSecond = null; return candidates; } XMPPConnection conn = serviceNode.getConnection(); JingleChannelIQ ciq = null; if (serviceNode != null) { final TrackerEntry preferred = serviceNode.getPreferedRelay(); if (preferred != null) { ciq = SmackServiceNode.getChannel(conn, preferred.getJid()); } } if (ciq != null) { ip = ciq.getHost(); port = ciq.getRemoteport(); if (logger.isInfoEnabled()) { logger.info( "JN relay: " + ip + " remote port:" + port + " local port: " + ciq.getLocalport()); } if (ip == null || ciq.getRemoteport() == 0) { logger.warn("JN relay ignored because ip was null or port 0"); return candidates; } // Drop the scope or interface name if the relay sends it // along in its IPv6 address. The scope/ifname is only valid on the // host that owns the IP and we don't need it here. int scopeIndex = ip.indexOf('%'); if (scopeIndex > 0) { logger.warn("Dropping scope from assumed IPv6 address " + ip); ip = ip.substring(0, scopeIndex); } /* RTP */ TransportAddress relayedAddress = new TransportAddress(ip, port, Transport.UDP); TransportAddress localAddress = new TransportAddress(ip, ciq.getLocalport(), Transport.UDP); LocalCandidate local = createJingleNodesCandidate(relayedAddress, component, localAddress); /* RTCP */ relayedAddressSecond = new TransportAddress(ip, port + 1, Transport.UDP); localAddressSecond = new TransportAddress(ip, ciq.getLocalport() + 1, Transport.UDP); // try to add the candidate to the component and then only add it to // the harvest not redundant (not sure how it could be red. but ...) if (component.addLocalCandidate(local)) { candidates.add(local); } } return candidates; }
/** * Log an exception. * * @param ex the exception that we are to log. */ public void logException(Throwable ex) { logger.warn("Exception in the JAIN-SIP stack: " + ex.getMessage()); if (logger.isInfoEnabled()) logger.info("JAIN-SIP exception stack trace is", ex); }
/** * Updates this view i.e. <tt>OneToOneCallPeerPanel</tt> so that it depicts the current state of * its model i.e. <tt>callPeer</tt>. The update is performed in the AWT event dispatching thread. */ private void updateViewFromModelInEventDispatchThread() { /* * We receive events/notifications from various threads and we respond * to them in the AWT event dispatching thread. It is possible to first * schedule an event to be brought to the AWT event dispatching thread, * then to have #dispose() invoked on this instance and, finally, to * receive the scheduled event in the AWT event dispatching thread. In * such a case, this disposed instance should not respond to the event * because it may, for example, steal a visual Components depicting * video (which cannot belong to more than one parent at a time) from * another non-disposed OneToOneCallPeerPanel. */ if (disposed) return; /* * Update the display of visual <tt>Component</tt>s depicting video * streaming between the local peer/user and the remote peer(s). */ OperationSetVideoTelephony videoTelephony = callPeer.getProtocolProvider().getOperationSet(OperationSetVideoTelephony.class); Component remoteVideo = null; Component localVideo = null; if (videoTelephony != null) { List<Component> remoteVideos = videoTelephony.getVisualComponents(callPeer); if ((remoteVideos != null) && !remoteVideos.isEmpty()) { /* * TODO OneToOneCallPeerPanel displays a one-to-one conversation * between the local peer/user and a specific remote peer. If * the remote peer is the focus of a telephony conference of its * own, it may be sending multiple videos to the local peer. * Switching to a user interface which displays multiple videos * is the responsibility of whoever decided that this * OneToOneCallPeerPanel is to be used to depict the current * state of the CallConference associated with the CallPeer * depicted by this instance. If that switching decides that * this instance is to continue being the user interface, then * we should probably pick up the remote video which is * generated by the remote peer and not one of its * ConferenceMembers. */ remoteVideo = remoteVideos.get(0); } if (uiVideoHandler.isLocalVideoVisible()) { try { localVideo = videoTelephony.getLocalVisualComponent(callPeer); } catch (OperationFailedException ofe) { /* * Well, we cannot do much about the exception. We'll just * not display the local video. */ logger.warn("Failed to retrieve local video to be displayed.", ofe); } } /* * Determine whether there is actually a change in the local and * remote videos which requires an update. */ boolean localVideoChanged = ((localVideo != this.localVideo) || ((localVideo != null) && !UIVideoHandler2.isAncestor(center, localVideo))); boolean remoteVideoChanged = ((remoteVideo != this.remoteVideo) || ((remoteVideo != null) && !UIVideoHandler2.isAncestor(center, remoteVideo))); // If the remote video has changed, maybe the CallPanel can display // the LO/SD/HD button. if (remoteVideoChanged) { // Updates video component which may listen the mouse and key // events. if (desktopSharingMouseAndKeyboardListener != null) { desktopSharingMouseAndKeyboardListener.setVideoComponent(remoteVideo); } CallPanel callPanel = callRenderer.getCallContainer(); // The remote video has been added, then tries to display the // LO/SD/HD button. if (remoteVideo != null) { callPanel.addRemoteVideoSpecificComponents(callPeer); } // The remote video has been removed, then hide the LO/SD/HD // button if it is currently displayed. else { callPanel.removeRemoteVideoSpecificComponents(); } } if (localVideoChanged || remoteVideoChanged) { /* * VideoContainer and JAWTRenderer cannot handle random * additions of Components. Removing the localVideo when the * user has requests its hiding though, should work without * removing all Components from the VideoCotainer and adding * them again. */ if (localVideoChanged && !remoteVideoChanged && (localVideo == null)) { if (this.localVideo != null) { center.remove(this.localVideo); this.localVideo = null; if (closeLocalVisualComponentButton != null) center.remove(closeLocalVisualComponentButton); } } else { center.removeAll(); this.localVideo = null; this.remoteVideo = null; /* * AWT does not make a guarantee about the Z order even * within an operating system i.e. the order of adding the * Components to their Container does not mean that they * will be determinedly painted in that or reverse order. * Anyway, there appears to be an expectation among the * developers less acquainted with AWT that AWT paints the * Components of a Container in an order that is the reverse * of the order of their adding. In order to satisfy that * expectation and thus give at least some idea to the * developers reading the code bellow, do add the Components * according to that expectation. */ if (localVideo != null) { if (closeLocalVisualComponentButton == null) { closeLocalVisualComponentButton = new CloseLocalVisualComponentButton(uiVideoHandler); } center.add(closeLocalVisualComponentButton, VideoLayout.CLOSE_LOCAL_BUTTON, -1); center.add(localVideo, VideoLayout.LOCAL, -1); this.localVideo = localVideo; } if (remoteVideo != null) { center.add(remoteVideo, VideoLayout.CENTER_REMOTE, -1); this.remoteVideo = remoteVideo; } } } } }
/** * Creates an account for the given user and password. * * @param providerFactory the ProtocolProviderFactory which will create the account * @param userName the user identifier * @param passwd the password * @return the <tt>ProtocolProviderService</tt> for the new account. * @throws OperationFailedException if the operation didn't succeed */ protected ProtocolProviderService installAccount( ProtocolProviderFactory providerFactory, String userName, String passwd) throws OperationFailedException { if (logger.isTraceEnabled()) { logger.trace("Preparing to install account for user " + userName); } Hashtable<String, String> accountProperties = new Hashtable<String, String>(); String protocolIconPath = getProtocolIconPath(); String accountIconPath = getAccountIconPath(); registration.storeProperties( userName, passwd, protocolIconPath, accountIconPath, accountProperties); accountProperties.put( ProtocolProviderFactory.IS_PREFERRED_PROTOCOL, Boolean.toString(isPreferredProtocol())); accountProperties.put(ProtocolProviderFactory.PROTOCOL, getProtocol()); if (isModification()) { providerFactory.modifyAccount(protocolProvider, accountProperties); setModification(false); return protocolProvider; } try { if (logger.isTraceEnabled()) { logger.trace( "Will install account for user " + userName + " with the following properties." + accountProperties); } AccountID accountID = providerFactory.installAccount(userName, accountProperties); ServiceReference serRef = providerFactory.getProviderForAccount(accountID); protocolProvider = (ProtocolProviderService) JabberAccRegWizzActivator.bundleContext.getService(serRef); } catch (IllegalArgumentException exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Username, password or server is null.", OperationFailedException.ILLEGAL_ARGUMENT); } catch (IllegalStateException exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Account already exists.", OperationFailedException.IDENTIFICATION_CONFLICT); } catch (Throwable exc) { logger.warn(exc.getMessage()); throw new OperationFailedException( "Failed to add account.", OperationFailedException.GENERAL_ERROR); } return protocolProvider; }
/** * Prints the specified <tt>exception</tt> as a warning. * * @param exception the <tt>Exception</tt> we are passed from jain-sip. */ public void logException(Exception exception) { logger.warn("the following exception occured in JAIN-SIP: " + exception, exception); }