# HG changeset patch # User Nikita Kozlov # Date 1338906565 -7200 # Node ID d7ddcccdff8a02e40d6908ed6df0aa79c9dc69a3 # Parent 6c2c4bfa43d04d67ff586a1c0dc44554f9da150d# Parent 55c27ccbd9f55efd630da5d7aa176e6f7006acae sync with trunk + using last asmack version diff -r 6c2c4bfa43d0 -r d7ddcccdff8a .hgtags --- a/.hgtags Tue Jan 18 00:26:02 2011 +0100 +++ b/.hgtags Tue Jun 05 16:29:25 2012 +0200 @@ -6,3 +6,10 @@ 1b88edb34d96acb5795b8d28e58b974f1bf2c1d6 0.1.4_rc 887b6a1fd9662312bf1ec271f9735369ead04cad 0.1.4 cf5db8d24b2a28ca501cc3e076abc55b38b41d90 0.1.4 +7b54215139deae5ba9307b7a165f24d65f926938 0.1.5_rc1 +8d19f91dd64c7f29f137b3236fb38c2cbcf98a36 0.1.5 +3b5e81bf741ae4fd47e239f889fb66ae6732dbd6 0.1.6_rc1 +18b31fdfb292b1405c5783f1d11be8cef9302087 0.1.6 +9f4ff6618111421f88eb38bf388ab0b1e3687317 0.1.7_rc1 +afff9e2452d91dba0e02672e6782fbbca6680fec 0.1.7_rc2 +5a6ab49303d3fe3e24661875a85158929bc22b5f 0.1.7 diff -r 6c2c4bfa43d0 -r d7ddcccdff8a AndroidManifest.xml --- a/AndroidManifest.xml Tue Jan 18 00:26:02 2011 +0100 +++ b/AndroidManifest.xml Tue Jun 05 16:29:25 2012 +0200 @@ -1,10 +1,10 @@ + package="com.beem.project.beem" android:versionCode="12" + android:versionName="0.1.7" android:installLocation="auto"> + android:name=".BeemApplication"> @@ -16,65 +16,30 @@ - - - - - + - - - - + android:launchMode="singleTop" /> - - - - - - - - - - - - - - + android:launchMode="singleTop" + android:windowSoftInputMode="stateHidden" /> + + + - - - - - - - - - - - - - - + android:launchMode="singleTask" /> + + + + + + + + - - @@ -99,7 +66,8 @@ - + + diff -r 6c2c4bfa43d0 -r d7ddcccdff8a CREDITS --- a/CREDITS Tue Jan 18 00:26:02 2011 +0100 +++ b/CREDITS Tue Jun 05 16:29:25 2012 +0200 @@ -18,6 +18,9 @@ Daniel Hofmann for german translations Andrea Selva for italian translations Erik Lindström for swedish translations +Murilo Ferraz Franco for portuguese translations +Alexei Emanov for russian translations +Karol Ptasinski for Norwegian translations Thanks to all ! diff -r 6c2c4bfa43d0 -r d7ddcccdff8a build.properties --- a/build.properties Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -external-libs=libs -javadoc-output=doc/javadoc - diff -r 6c2c4bfa43d0 -r d7ddcccdff8a build.xml --- a/build.xml Tue Jan 18 00:26:02 2011 +0100 +++ b/build.xml Tue Jun 05 16:29:25 2012 +0200 @@ -1,82 +1,100 @@ - + + It contains the path to the SDK. It should *NOT* be checked into + Version Control Systems. --> - - - - - + - - - - - - - - + - + This file is an integral part of the build system for your + application and should be checked into Version Control Systems. --> + - - - - - + + + + + + + + + + - + + + + + + + + + + + diff -r 6c2c4bfa43d0 -r d7ddcccdff8a default.properties --- a/default.properties Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "build.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-7 diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/UmlGraph.jar Binary file doc/UmlGraph.jar has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/README.txt --- a/doc/asmack-beem/README.txt Tue Jan 18 00:26:02 2011 +0100 +++ b/doc/asmack-beem/README.txt Tue Jun 05 16:29:25 2012 +0200 @@ -14,26 +14,13 @@ ------- First check out the last version of asmack -> git clone git://github.com/rtreffer/asmack.git - -Then apply the beem-build-process.patch on the source. -> cd asmack -> patch -p1 < beem-build-process.patch -> +> git://github.com/klnikita/asmack.git -Add the beem flavour to the patch repository -> cp -R beem_patches patch/beem -> - -The 50-fix_chatmanager.patch is only necessary to fix a little bug in smack. The -patch has been proposed to the Smack developers. See -http://www.igniterealtime.org/issues/browse/SMACK-269 for progress. - -Edit your local.properties file to contains the path of the android SDK. See -local.properties.example +In the asmack folder, edit your local.properties file to contains the path of the android SDK. +See local.properties.example Build asmack -> ./build.batch +> ./build.batch -j -c > The build directory will contains the files : diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem-build-process.patch --- a/doc/asmack-beem/beem-build-process.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -diff --git a/build.bash b/build.bash -index ce793f9..26e4560 100755 ---- a/build.bash -+++ b/build.bash -@@ -15,11 +15,11 @@ fetch() { - if ! [ -f "${2}/.svn/entries" ]; then - mkdir "${2}" - cd "${2}" -- svn co --non-interactive --trust-server-cert "${1}" "." -+ svn co --non-interactive --trust-server-cert "${1}" -r "${3}" "." - else - cd "${2}" - svn cleanup -- svn up -+ svn up -r "${3}" - fi - ) - } -@@ -37,11 +37,11 @@ gitfetch() { - } - - fetchall() { -- gitfetch "git://github.com/rtreffer/smack.git" "smack" -- fetch "http://svn.apache.org/repos/asf/qpid/trunk/qpid/java/management/common/src/main/" "qpid" -- fetch "http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/auth/src/main/java/common/" "harmony" -- fetch "https://dnsjava.svn.sourceforge.net/svnroot/dnsjava/trunk" "dnsjava" -- fetch "https://kenai.com/svn/jbosh~main/trunk/jbosh/src/main/java" "jbosh" -+ fetch "http://svn.igniterealtime.org/svn/repos/smack/trunk" "smack" "11644" -+ fetch "http://svn.apache.org/repos/asf/qpid/trunk/qpid/java/management/common/src/main/" "qpid" "HEAD" -+ fetch "http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/auth/src/main/java/common/" "harmony" "HEAD" -+ fetch "https://dnsjava.svn.sourceforge.net/svnroot/dnsjava/trunk" "dnsjava" "HEAD" -+ fetch "https://kenai.com/svn/jbosh~main/trunk/jbosh/src/main/java" "jbosh" "HEAD" - } - - copyfolder() { -@@ -62,6 +62,7 @@ buildsrc() { - mkdir build/src - mkdir build/src/trunk - copyfolder "src/smack/source/" "build/src/trunk" "." -+ copyfolder "src/smack/jingle/extension/source/" "build/src/trunk" "." - copyfolder "src/qpid/java" "build/src/trunk" "org/apache/qpid/management/common/sasl" - copyfolder "src/novell-openldap-jldap" "build/src/trunk" "." - copyfolder "src/dnsjava" "build/src/trunk" "org" -diff --git a/build.xml b/build.xml -index 827f4c5..50054f1 100644 ---- a/build.xml -+++ b/build.xml -@@ -57,7 +57,7 @@ - target="1.5" - srcdir="build/src/trunk" - destdir="build/classes/trunk" -- classpath="lib/xmlpull_1_1_3_4c.jar" -+ classpath="lib/xmlpull_1_1_3_4c.jar:lib/jstun.jar" - bootclasspath="${sdk-location}/platforms/android-7/android.jar" - debug="true" - debuglevel="source,lines" -@@ -85,7 +85,7 @@ - target="1.5" - srcdir="build/src/trunk" - destdir="build/classes/trunk" -- classpath="lib/xmlpull_1_1_3_4c.jar" -+ classpath="lib/xmlpull_1_1_3_4c.jar:lib/jstun.jar" - bootclasspath="${sdk-location}/platforms/android-6/android.jar" - debug="true" - debuglevel="source,lines" -@@ -113,7 +113,7 @@ - target="1.5" - srcdir="build/src/trunk" - destdir="build/classes/trunk" -- classpath="lib/xmlpull_1_1_3_4c.jar" -+ classpath="lib/xmlpull_1_1_3_4c.jar:lib/jstun.jar" - bootclasspath="${sdk-location}/platforms/android-5/android.jar" - debug="true" - debuglevel="source,lines" -@@ -141,7 +141,7 @@ - target="1.5" - srcdir="build/src/trunk" - destdir="build/classes/trunk" -- classpath="lib/xmlpull_1_1_3_4c.jar" -+ classpath="lib/xmlpull_1_1_3_4c.jar:lib/jstun.jar" - bootclasspath="${sdk-location}/platforms/android-4/android.jar" - debug="true" - debuglevel="source,lines" diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/10-PubSubManager-non-final.patch --- a/doc/asmack-beem/beem_patches/10-PubSubManager-non-final.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -Index: org/jivesoftware/smackx/pubsub/PubSubManager.java -=================================================================== ---- org/jivesoftware/smackx/pubsub/PubSubManager.java (revision 11464) -+++ org/jivesoftware/smackx/pubsub/PubSubManager.java (working copy) -@@ -41,7 +41,7 @@ - * - * @author Robin Collier - */ --final public class PubSubManager -+public class PubSubManager - { - private XMPPConnection con; - private String to; diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/50-fix-chatmanager.patch --- a/doc/asmack-beem/beem_patches/50-fix-chatmanager.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ - Copyright (C) 2010 by Frederic-Charles Barthelery, - Jean-Manuel Da Silva, - Nikita Kozlov, - Philippe Lago, - Jean Baptiste Vergely, - Vincent Veronis. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ---- ../../../src/smack/org/jivesoftware/smack/ChatManager.java 2010-02-23 19:27:26.000000000 +0100 -+++ org/jivesoftware/smack/ChatManager.java 2010-02-23 19:37:47.000000000 +0100 -@@ -111,7 +111,9 @@ - chat = getUserChat(message.getFrom()); - } - } -- -+ if (chat == null) { -+ chat = getUserChat(StringUtils.parseBareAddress(message.getFrom())); -+ } - if(chat == null) { - chat = createChat(message); - } diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/50-fix-sasl-incorrect-encoding.patch --- a/doc/asmack-beem/beem_patches/50-fix-sasl-incorrect-encoding.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ - Copyright (C) 2010 by Frederic-Charles Barthelery, - Jean-Manuel Da Silva, - Nikita Kozlov, - Philippe Lago, - Jean Baptiste Vergely, - Vincent Veronis. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ---- org/jivesoftware/smack/sasl/SASLMechanism.java~ 2010-07-20 15:13:25.000000000 +0200 -+++ org/jivesoftware/smack/sasl/SASLMechanism.java 2010-07-20 15:15:41.000000000 +0200 -@@ -263,9 +263,6 @@ - if (authenticationText != null) { - stanza.append(authenticationText); - } -- else { -- stanza.append("="); -- } - stanza.append(""); - return stanza.toString(); - } diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/50-improved-pubsub.patch --- a/doc/asmack-beem/beem_patches/50-improved-pubsub.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ ---- ../../../src/smack/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java (révision 11644) -+++ org/jivesoftware/smackx/pubsub/provider/ItemProvider.java (copie de travail) -@@ -45,6 +45,8 @@ - } - else - { -+ while (tag != XmlPullParser.START_TAG) -+ tag = parser.next(); - String payloadElemName = parser.getName(); - String payloadNS = parser.getNamespace(); - ---- ../../../src/org/jivesoftware/smackx/pubsub/Node.java (révision 11644) -+++ org/jivesoftware/smackx/pubsub/Node.java (copie de travail) -@@ -60,7 +60,7 @@ - * - * For example, OpenFire requires the server to be prefixed by pubsub - */ -- void setTo(String toAddress) -+ public void setTo(String toAddress) - { - to = toAddress; - } ---- ../../../src/org/jivesoftware/smackx/pubsub/LeafNode.java (révision 11644) -+++ org/jivesoftware/smackx/pubsub/LeafNode.java (copie de travail) -@@ -34,7 +34,7 @@ - */ - public class LeafNode extends Node - { -- LeafNode(Connection connection, String nodeName) -+ public LeafNode(Connection connection, String nodeName) - { - super(connection, nodeName); - } ---- ../../../src/org/jivesoftware/smackx/pubsub/PubSubManager.java (révision 11644) -+++ org/jivesoftware/smackx/pubsub/PubSubManager.java (copie de travail) -@@ -43,8 +43,8 @@ - */ - final public class PubSubManager - { -- private Connection con; -- private String to; -+ protected Connection con; -+ protected String to; - private Map nodeMap = new ConcurrentHashMap(); - - /** diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/50-jingle-ext.patch --- a/doc/asmack-beem/beem_patches/50-jingle-ext.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -Index: org/jivesoftware/smackx/packet/JingleContentInfo.java -=================================================================== ---- org/jivesoftware/smackx/packet/JingleContentInfo.java (revision 11644) -+++ org/jivesoftware/smackx/packet/JingleContentInfo.java (working copy) -@@ -96,7 +96,7 @@ - */ - public static class Audio extends JingleContentInfo { - -- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp"; -+ public static final String NAMESPACE = "urn:xmpp:jingle:apps:rtp:1"; - - public Audio(final ContentInfo mi) { - super(mi); -Index: org/jivesoftware/smackx/packet/JingleError.java -=================================================================== ---- org/jivesoftware/smackx/packet/JingleError.java (revision 11644) -+++ org/jivesoftware/smackx/packet/JingleError.java (working copy) -@@ -27,7 +27,7 @@ - - public class JingleError implements PacketExtension { - -- public static String NAMESPACE = "urn:xmpp:tmp:jingle:errors"; -+ public static String NAMESPACE = "urn:xmpp:jingle:errors:1"; - - public static final JingleError OUT_OF_ORDER = new JingleError("out-of-order"); - -Index: org/jivesoftware/smackx/packet/JingleTransport.java -=================================================================== ---- org/jivesoftware/smackx/packet/JingleTransport.java (revision 11644) -+++ org/jivesoftware/smackx/packet/JingleTransport.java (working copy) -@@ -270,7 +270,7 @@ - * RTP-ICE profile - */ - public static class Ice extends JingleTransport { -- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:transports:ice-udp"; -+ public static final String NAMESPACE = "urn:xmpp:jingle:transports:ice-udp:1"; - - public Ice() { - super(); -@@ -352,7 +352,7 @@ - * Raw UDP profile. - */ - public static class RawUdp extends JingleTransport { -- public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0177.html#ns"; -+ public static final String NAMESPACE = "urn:xmpp:jingle:transports:raw-udp:1"; - - public RawUdp() { - super(); -Index: org/jivesoftware/smackx/packet/JingleContentDescription.java -=================================================================== ---- org/jivesoftware/smackx/packet/JingleContentDescription.java (revision 11644) -+++ org/jivesoftware/smackx/packet/JingleContentDescription.java (working copy) -@@ -66,6 +66,13 @@ - public abstract String getNamespace(); - - /** -+ * Return the media type. -+ * -+ * @return The media type -+ */ -+ public abstract String getMediaType(); -+ -+ /** - * Adds a audio payload type to the packet. - * - * @param pt the audio payload type to add. -@@ -153,7 +160,8 @@ - synchronized (payloads) { - if (payloads.size() > 0) { - buf.append("<").append(getElementName()); -- buf.append(" xmlns=\"").append(getNamespace()).append("\" >"); -+ buf.append(" xmlns=\"").append(getNamespace()).append("\""); -+ buf.append(" media=\"").append(getMediaType()).append("\" >"); - - Iterator pt = payloads.listIterator(); - while (pt.hasNext()) { -@@ -172,7 +180,8 @@ - */ - public static class Audio extends JingleContentDescription { - -- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp"; -+ public static final String NAMESPACE = "urn:xmpp:jingle:apps:rtp:1"; -+ public static final String MEDIA_TYPE = "audio"; - - public Audio() { - super(); -@@ -189,6 +198,10 @@ - public String getNamespace() { - return NAMESPACE; - } -+ -+ public String getMediaType() { -+ return MEDIA_TYPE; -+ } - } - - /** -Index: org/jivesoftware/smackx/packet/Jingle.java -=================================================================== ---- org/jivesoftware/smackx/packet/Jingle.java (revision 11644) -+++ org/jivesoftware/smackx/packet/Jingle.java (working copy) -@@ -44,7 +44,7 @@ - - // static - -- public static final String NAMESPACE = "urn:xmpp:tmp:jingle"; -+ public static final String NAMESPACE = "urn:xmpp:jingle:1"; - - public static final String NODENAME = "jingle"; - -Index: org/jivesoftware/smackx/packet/JingleDescription.java -=================================================================== ---- org/jivesoftware/smackx/packet/JingleDescription.java (revision 11644) -+++ org/jivesoftware/smackx/packet/JingleDescription.java (working copy) -@@ -69,6 +69,13 @@ - public abstract String getNamespace(); - - /** -+ * Return the media type. -+ * -+ * @return The media type -+ */ -+ public abstract String getMediaType(); -+ -+ /** - * Adds a audio payload type to the packet. - * - * @param pt the audio payload type to add. -@@ -160,7 +167,8 @@ - synchronized (payloads) { - if (payloads.size() > 0) { - buf.append("<").append(getElementName()); -- buf.append(" xmlns=\"").append(getNamespace()).append("\" >"); -+ buf.append(" xmlns=\"").append(getNamespace()).append("\""); -+ buf.append(" media=\"").append(getMediaType()).append("\" >"); - - for (PayloadType payloadType : payloads) { - if (payloadType != null) { -@@ -179,7 +187,8 @@ - */ - public static class Audio extends JingleDescription { - -- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp"; -+ public static final String NAMESPACE = "urn:xmpp:jingle:apps:rtp:1"; -+ public static final String MEDIA_TYPE = "audio"; - - public Audio() { - super(); -@@ -196,5 +205,9 @@ - public String getNamespace() { - return NAMESPACE; - } -+ -+ public String getMediaType() { -+ return MEDIA_TYPE; -+ } - } - } -Index: org/jivesoftware/smackx/jingle/JingleManager.java -=================================================================== ---- org/jivesoftware/smackx/jingle/JingleManager.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/JingleManager.java (working copy) -@@ -255,7 +255,7 @@ - */ - public static void setJingleServiceEnabled() { - ProviderManager providerManager = ProviderManager.getInstance(); -- providerManager.addIQProvider("jingle", "urn:xmpp:tmp:jingle", new JingleProvider()); -+ providerManager.addIQProvider("jingle", "urn:xmpp:jingle:1", new JingleProvider()); - - // Enable the Jingle support on every established connection - // The ServiceDiscoveryManager class should have been already -@@ -598,4 +598,4 @@ - } - return null; - } --} -\ No newline at end of file -+} diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/50-public-info-features.patch --- a/doc/asmack-beem/beem_patches/50-public-info-features.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ - Copyright (C) 2010 by Frederic-Charles Barthelery, - Jean-Manuel Da Silva, - Nikita Kozlov, - Philippe Lago, - Jean Baptiste Vergely, - Vincent Veronis. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ---- org/jivesoftware/smackx/packet/DiscoverInfo.java 2010-07-22 22:16:27.000000000 +0200 -+++ org/jivesoftware/smackx/packet/DiscoverInfo.java 2010-07-22 22:58:43.000000000 +0200 -@@ -62,7 +62,7 @@ - * - * @return an Iterator on the discovered features of an XMPP entity - */ -- Iterator getFeatures() { -+ public Iterator getFeatures() { - synchronized (features) { - return Collections.unmodifiableList(features).iterator(); - } -@@ -266,4 +266,4 @@ - return buf.toString(); - } - } --} -\ Pas de fin de ligne à la fin du fichier. -+} diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/50-remove-jingle_mediaimpl.patch --- a/doc/asmack-beem/beem_patches/50-remove-jingle_mediaimpl.patch Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4039 +0,0 @@ -Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java (working copy) -@@ -1,92 +0,0 @@ --/** -- * $RCSfile: TestMediaSession.java,v $ -- * $Revision: 1.1 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --package org.jivesoftware.smackx.jingle.mediaimpl.test; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --/** -- * This Class implements a complete JingleMediaSession for unit testing. -- * -- * @author Thiago Camargo -- */ --public class TestMediaSession extends JingleMediaSession { -- -- /** -- * Creates a TestMediaSession with defined payload type, remote and local candidates -- * -- * @param payloadType Payload of the jmf -- * @param remote the remote information. The candidate that the jmf will be sent to. -- * @param local the local information. The candidate that will receive the jmf -- * @param locator media locator -- */ -- public TestMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, -- final String locator, JingleSession jingleSession) { -- super(payloadType, remote, local, "Test", jingleSession); -- initialize(); -- } -- -- /** -- * Initialize the screen share channels. -- */ -- public void initialize() { -- -- } -- -- /** -- * Starts transmission and for NAT Traversal reasons start receiving also. -- */ -- public void startTrasmit() { -- -- } -- -- /** -- * Set transmit activity. If the active is true, the instance should trasmit. -- * If it is set to false, the instance should pause transmit. -- * -- * @param active active state -- */ -- public void setTrasmit(boolean active) { -- -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void startReceive() { -- // Do nothing -- } -- -- /** -- * Stops transmission and for NAT Traversal reasons stop receiving also. -- */ -- public void stopTrasmit() { -- -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void stopReceive() { -- -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java (working copy) -@@ -1,93 +0,0 @@ --/** -- * $RCSfile: TestMediaManager.java,v $ -- * $Revision: 1.3 $ -- * $Date: 25/12/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.test; -- --import org.jivesoftware.smackx.jingle.media.JingleMediaManager; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; --import org.jivesoftware.smackx.jingle.JingleSession; -- --import java.util.*; -- --/** -- * Implements a MediaManager for test purposes. -- * -- * @author Thiago Camargo -- */ -- --public class TestMediaManager extends JingleMediaManager { -- -- public static final String MEDIA_NAME = "TestMedia"; -- -- private List payloads = new ArrayList(); -- -- private PayloadType preferredPayloadType = null; -- -- public TestMediaManager(JingleTransportManager transportManager) { -- super(transportManager); -- } -- -- /** -- * Return all supported Payloads for this Manager. -- * -- * @return The Payload List -- */ -- public List getPayloads() { -- return payloads; -- } -- -- public void setPayloads(List payloads) { -- this.payloads.addAll(payloads); -- } -- -- /** -- * Returns a new JingleMediaSession -- * -- * @param payloadType payloadType -- * @param remote remote Candidate -- * @param local local Candidate -- * @return JingleMediaSession JingleMediaSession -- */ -- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, -- final TransportCandidate local, final JingleSession jingleSession) { -- TestMediaSession session = null; -- -- session = new TestMediaSession(payloadType, remote, local, "", jingleSession); -- -- return session; -- } -- -- public PayloadType getPreferredPayloadType() { -- if (preferredPayloadType != null) -- return preferredPayloadType; -- return super.getPreferredPayloadType(); -- } -- -- public void setPreferredPayloadType(PayloadType preferredPayloadType) { -- this.preferredPayloadType = preferredPayloadType; -- } -- -- public String getName() { -- return MEDIA_NAME; -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java (working copy) -@@ -1,282 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl; -- --import java.awt.Frame; --import java.awt.TextArea; --import java.awt.Toolkit; --import java.util.Vector; -- --import javax.media.Format; --import javax.media.PlugInManager; --import javax.media.Renderer; --import javax.media.format.AudioFormat; -- --import org.jivesoftware.smackx.jingle.SmackLogger; -- --import com.sun.media.ExclusiveUse; --import com.sun.media.util.Registry; -- --public class JMFInit extends Frame implements Runnable { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(JMFInit.class); -- -- private String tempDir = "/tmp"; -- -- private boolean done = false; -- -- private String userHome; -- -- private boolean visible = false; -- -- public JMFInit(String[] args, boolean visible) { -- super("Initializing JMF..."); -- -- this.visible = visible; -- -- Registry.set("secure.allowCaptureFromApplets", true); -- Registry.set("secure.allowSaveFileFromApplets", true); -- -- updateTemp(args); -- -- try { -- Registry.commit(); -- } -- catch (Exception e) { -- -- message("Failed to commit to JMFRegistry!"); -- } -- -- Thread detectThread = new Thread(this); -- detectThread.run(); -- -- /* -- * int slept = 0; while (!done && slept < 60 * 1000 * 2) { try { -- * Thread.currentThread().sleep(500); } catch (InterruptedException ie) { } -- * slept += 500; } -- * -- * if (!done) { console.error("Detection is taking too long! -- * Aborting!"); message("Detection is taking too long! Aborting!"); } -- * -- * try { Thread.currentThread().sleep(2000); } catch -- * (InterruptedException ie) { } -- */ -- } -- -- public void run() { -- detectDirectAudio(); -- detectS8DirectAudio(); -- detectCaptureDevices(); -- done = true; -- } -- -- private void updateTemp(String[] args) { -- if (args != null && args.length > 0) { -- tempDir = args[0]; -- -- message("Setting cache directory to " + tempDir); -- Registry r = new Registry(); -- try { -- r.set("secure.cacheDir", tempDir); -- r.commit(); -- -- message("Updated registry"); -- } -- catch (Exception e) { -- message("Couldn't update registry!"); -- } -- } -- } -- -- private void detectCaptureDevices() { -- // check if JavaSound capture is available -- message("Looking for Audio capturer"); -- Class dsauto; -- try { -- dsauto = Class.forName("DirectSoundAuto"); -- dsauto.newInstance(); -- message("Finished detecting DirectSound capturer"); -- } -- catch (ThreadDeath td) { -- throw td; -- } -- catch (Throwable t) { -- //Do nothing -- } -- -- Class jsauto; -- try { -- jsauto = Class.forName("JavaSoundAuto"); -- jsauto.newInstance(); -- message("Finished detecting javasound capturer"); -- } -- catch (ThreadDeath td) { -- throw td; -- } -- catch (Throwable t) { -- message("JavaSound capturer detection failed!"); -- } -- -- /* -- // Check if VFWAuto or SunVideoAuto is available -- message("Looking for video capture devices"); -- Class auto = null; -- Class autoPlus = null; -- try { -- auto = Class.forName("VFWAuto"); -- } -- catch (Exception e) { -- } -- if (auto == null) { -- try { -- auto = Class.forName("SunVideoAuto"); -- } -- catch (Exception ee) { -- -- } -- try { -- autoPlus = Class.forName("SunVideoPlusAuto"); -- } -- catch (Exception ee) { -- -- } -- } -- if (auto == null) { -- try { -- auto = Class.forName("V4LAuto"); -- } -- catch (Exception ee) { -- -- } -- } -- try { -- Object instance = auto.newInstance(); -- if (autoPlus != null) { -- Object instancePlus = autoPlus.newInstance(); -- } -- -- message("Finished detecting video capture devices"); -- } -- catch (ThreadDeath td) { -- throw td; -- } -- catch (Throwable t) { -- -- message("Capture device detection failed!"); -- } -- */ -- } -- -- private void detectDirectAudio() { -- Class cls; -- int plType = PlugInManager.RENDERER; -- String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; -- try { -- // Check if this is the Windows Performance Pack - hack -- cls = Class.forName("VFWAuto"); -- // Check if DS capture is supported, otherwise fail DS renderer -- // since NT doesn't have capture -- cls = Class.forName("com.sun.media.protocol.dsound.DSound"); -- // Find the renderer class and instantiate it. -- cls = Class.forName(dar); -- -- Renderer rend = (Renderer) cls.newInstance(); -- try { -- // Set the format and open the device -- AudioFormat af = new AudioFormat(AudioFormat.LINEAR, 44100, 16, -- 2); -- rend.setInputFormat(af); -- rend.open(); -- Format[] inputFormats = rend.getSupportedInputFormats(); -- // Register the device -- PlugInManager.addPlugIn(dar, inputFormats, new Format[0], -- plType); -- // Move it to the top of the list -- Vector rendList = PlugInManager.getPlugInList(null, null, -- plType); -- int listSize = rendList.size(); -- if (rendList.elementAt(listSize - 1).equals(dar)) { -- rendList.removeElementAt(listSize - 1); -- rendList.insertElementAt(dar, 0); -- PlugInManager.setPlugInList(rendList, plType); -- PlugInManager.commit(); -- // Log.debug("registered"); -- } -- rend.close(); -- } -- catch (Throwable t) { -- // Log.debug("Error " + t); -- } -- } -- catch (Throwable tt) { -- //Do nothing -- } -- } -- -- private void detectS8DirectAudio() { -- Class cls; -- int plType = PlugInManager.RENDERER; -- String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; -- try { -- // Check if this is the solaris Performance Pack - hack -- cls = Class.forName("SunVideoAuto"); -- -- // Find the renderer class and instantiate it. -- cls = Class.forName(dar); -- -- Renderer rend = (Renderer) cls.newInstance(); -- -- if (rend instanceof ExclusiveUse -- && !((ExclusiveUse) rend).isExclusive()) { -- // sol8+, DAR supports mixing -- Vector rendList = PlugInManager.getPlugInList(null, null, -- plType); -- int listSize = rendList.size(); -- boolean found = false; -- String rname = null; -- -- for (int i = 0; i < listSize; i++) { -- rname = (String) (rendList.elementAt(i)); -- if (rname.equals(dar)) { // DAR is in the registry -- found = true; -- rendList.removeElementAt(i); -- break; -- } -- } -- -- if (found) { -- rendList.insertElementAt(dar, 0); -- PlugInManager.setPlugInList(rendList, plType); -- PlugInManager.commit(); -- } -- } -- } -- catch (Throwable tt) { -- //Do nothing -- } -- } -- -- private void message(String mesg) { -- LOGGER.debug(mesg); -- } -- -- private void createGUI() { -- TextArea textBox = new TextArea(5, 50); -- add("Center", textBox); -- textBox.setEditable(false); -- addNotify(); -- pack(); -- -- int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize() -- .getWidth(); -- int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize() -- .getHeight(); -- -- setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2); -- -- setVisible(visible); -- -- } -- -- public static void start(boolean visible) { -- new JMFInit(null, visible); -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java (working copy) -@@ -1,174 +0,0 @@ --/** -- * $RCSfile: Demo.java,v $ -- * $Revision: 1.3 $ -- * $Date: 28/12/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --package org.jivesoftware.smackx.jingle.mediaimpl.demo; -- --import org.jivesoftware.smack.Connection; --import org.jivesoftware.smack.XMPPConnection; --import org.jivesoftware.smack.XMPPException; --import org.jivesoftware.smackx.jingle.JingleManager; --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.JingleSessionRequest; --import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; --import org.jivesoftware.smackx.jingle.media.JingleMediaManager; --import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager; --import org.jivesoftware.smackx.jingle.nat.ICETransportManager; --import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; -- --import javax.swing.*; --import java.awt.event.ActionEvent; --import java.util.ArrayList; --import java.util.List; -- --/** -- * Jingle Demo Application. It register in a XMPP Server and let users place calls using a full JID and auto-receive calls. -- * Parameters: Server User Pass. -- */ --public class Demo extends JFrame { -- -- private JingleTransportManager transportManager = null; -- private Connection xmppConnection = null; -- -- private String server = null; -- private String user = null; -- private String pass = null; -- -- private JingleManager jm = null; -- private JingleSession incoming = null; -- private JingleSession outgoing = null; -- -- private JTextField jid; -- -- public Demo(String server, String user, String pass) { -- -- this.server = server; -- this.user = user; -- this.pass = pass; -- -- if (user.equals("jeffw")) { -- jid = new JTextField("eowyn" + "@" + server + "/Smack"); -- } else { -- jid = new JTextField("jeffw" + "@" + server + "/Smack"); -- } -- -- xmppConnection = new XMPPConnection(server); -- try { -- xmppConnection.connect(); -- xmppConnection.login(user, pass); -- initialize(); -- } -- catch (XMPPException e) { -- e.printStackTrace(); -- } -- } -- -- public void initialize() { -- ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "10.47.47.53", 3478); -- List mediaManagers = new ArrayList(); -- //mediaManagers.add(new JmfMediaManager(icetm0)); -- mediaManagers.add(new SpeexMediaManager(icetm0)); -- mediaManagers.add(new ScreenShareMediaManager(icetm0)); -- jm = new JingleManager(xmppConnection, mediaManagers); -- jm.addCreationListener(icetm0); -- -- jm.addJingleSessionRequestListener(new JingleSessionRequestListener() { -- public void sessionRequested(JingleSessionRequest request) { -- --// if (incoming != null) --// return; -- -- try { -- // Accept the call -- incoming = request.accept(); -- -- // Start the call -- incoming.startIncoming(); -- } -- catch (XMPPException e) { -- e.printStackTrace(); -- } -- -- } -- }); -- createGUI(); -- } -- -- public void createGUI() { -- -- JPanel jPanel = new JPanel(); -- -- jPanel.add(jid); -- -- jPanel.add(new JButton(new AbstractAction("Call") { -- public void actionPerformed(ActionEvent e) { -- if (outgoing != null) return; -- try { -- outgoing = jm.createOutgoingJingleSession(jid.getText()); -- outgoing.startOutgoing(); -- } -- catch (XMPPException e1) { -- e1.printStackTrace(); -- } -- } -- })); -- -- jPanel.add(new JButton(new AbstractAction("Hangup") { -- public void actionPerformed(ActionEvent e) { -- if (outgoing != null) -- try { -- outgoing.terminate(); -- } -- catch (XMPPException e1) { -- e1.printStackTrace(); -- } -- finally { -- outgoing = null; -- } -- if (incoming != null) -- try { -- incoming.terminate(); -- } -- catch (XMPPException e1) { -- e1.printStackTrace(); -- } -- finally { -- incoming = null; -- } -- } -- })); -- -- this.add(jPanel); -- -- } -- -- public static void main(String args[]) { -- -- Demo demo = null; -- -- if (args.length > 2) { -- demo = new Demo(args[0], args[1], args[2]); -- demo.pack(); -- demo.setVisible(true); -- demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); -- } -- -- } -- --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java (working copy) -@@ -1,206 +0,0 @@ --/** -- * $RCSfile: ScreenShareSession.java,v $ -- * $Revision: 1.2 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare; -- --import java.awt.Rectangle; --import java.awt.event.WindowAdapter; --import java.awt.event.WindowEvent; --import java.io.IOException; --import java.net.DatagramSocket; --import java.net.InetAddress; --import java.net.ServerSocket; --import java.net.UnknownHostException; -- --import javax.swing.JFrame; --import javax.swing.JPanel; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageReceiver; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --/** -- * This Class implements a complete JingleMediaSession. -- * It sould be used to transmit and receive captured images from the Display. -- * This Class should be automaticly controlled by JingleSession. -- * For better NAT Traversal support this implementation don't support only receive or only transmit. -- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit() -- * -- * @author Thiago Camargo -- */ --public class ScreenShareSession extends JingleMediaSession { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(ScreenShareSession.class); -- -- private ImageTransmitter transmitter = null; -- private ImageReceiver receiver = null; -- private int width = 600; -- private int height = 600; -- -- /** -- * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates -- * -- * @param payloadType Payload of the jmf -- * @param remote the remote information. The candidate that the jmf will be sent to. -- * @param local the local information. The candidate that will receive the jmf -- * @param locator media locator -- */ -- public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, -- final String locator, JingleSession jingleSession) { -- super(payloadType, remote, local, "Screen", jingleSession); -- initialize(); -- } -- -- /** -- * Initialize the screen share channels. -- */ -- public void initialize() { -- -- JingleSession session = getJingleSession(); -- if ((session != null) && (session.getInitiator().equals(session.getConnection().getUser()))) { -- // If the initiator of the jingle session is us then we transmit a screen share. -- try { -- InetAddress remote = InetAddress.getByName(getRemote().getIp()); -- transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(), -- new Rectangle(0, 0, width, height)); -- } catch (Exception e) { -- e.printStackTrace(); -- } -- -- } else { -- // Otherwise we receive a screen share. -- JFrame window = new JFrame(); -- JPanel jp = new JPanel(); -- window.add(jp); -- -- window.setLocation(0, 0); -- window.setSize(600, 600); -- -- window.addWindowListener(new WindowAdapter() { -- public void windowClosed(WindowEvent e) { -- receiver.stop(); -- } -- }); -- -- try { -- receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width, -- height); -- LOGGER.debug("Receiving on:" + receiver.getLocalPort()); -- } catch (UnknownHostException e) { -- e.printStackTrace(); -- } -- -- jp.add(receiver); -- receiver.setVisible(true); -- window.setAlwaysOnTop(true); -- window.setVisible(true); -- } -- } -- -- /** -- * Starts transmission and for NAT Traversal reasons start receiving also. -- */ -- public void startTrasmit() { -- new Thread(transmitter).start(); -- } -- -- /** -- * Set transmit activity. If the active is true, the instance should trasmit. -- * If it is set to false, the instance should pause transmit. -- * -- * @param active active state -- */ -- public void setTrasmit(boolean active) { -- transmitter.setTransmit(true); -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void startReceive() { -- // Do nothing -- } -- -- /** -- * Stops transmission and for NAT Traversal reasons stop receiving also. -- */ -- public void stopTrasmit() { -- if (transmitter != null) { -- transmitter.stop(); -- } -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void stopReceive() { -- if (receiver != null) { -- receiver.stop(); -- } -- } -- -- /** -- * Obtain a free port we can use. -- * -- * @return A free port number. -- */ -- protected int getFreePort() { -- ServerSocket ss; -- int freePort = 0; -- -- for (int i = 0; i < 10; i++) { -- freePort = (int) (10000 + Math.round(Math.random() * 10000)); -- freePort = freePort % 2 == 0 ? freePort : freePort + 1; -- try { -- ss = new ServerSocket(freePort); -- freePort = ss.getLocalPort(); -- ss.close(); -- return freePort; -- } catch (IOException e) { -- e.printStackTrace(); -- } -- } -- try { -- ss = new ServerSocket(0); -- freePort = ss.getLocalPort(); -- ss.close(); -- } catch (IOException e) { -- e.printStackTrace(); -- } -- return freePort; -- } -- -- public void setEncoder(ImageEncoder encoder) { -- if (encoder != null) { -- this.transmitter.setEncoder(encoder); -- } -- } -- -- public void setDecoder(ImageDecoder decoder) { -- if (decoder != null) { -- this.receiver.setDecoder(decoder); -- } -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java (working copy) -@@ -1,204 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.AWTException; --import java.awt.Rectangle; --import java.awt.Robot; --import java.awt.image.BufferedImage; --import java.awt.image.PixelGrabber; --import java.io.ByteArrayOutputStream; --import java.io.IOException; --import java.net.DatagramPacket; --import java.net.DatagramSocket; --import java.net.InetAddress; --import java.util.Arrays; -- --import org.jivesoftware.smackx.jingle.SmackLogger; -- --/** -- * UDP Image Receiver. -- * It uses PNG Tiles into UDP packets. -- * -- * @author Thiago Rocha Camargo -- */ --public class ImageTransmitter implements Runnable { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(ImageTransmitter.class); -- -- private Robot robot; -- private InetAddress localHost; -- private InetAddress remoteHost; -- private int localPort; -- private int remotePort; -- public static final int tileWidth = 25; -- private boolean on = true; -- private boolean transmit = false; -- private DatagramSocket socket; -- private Rectangle area; -- private int tiles[][][]; -- private int maxI; -- private int maxJ; -- private ImageEncoder encoder; -- public final static int KEYFRAME = 10; -- -- public ImageTransmitter(DatagramSocket socket, InetAddress remoteHost, int remotePort, Rectangle area) { -- -- try { -- robot = new Robot(); -- -- maxI = (int) Math.ceil(area.getWidth() / tileWidth); -- maxJ = (int) Math.ceil(area.getHeight() / tileWidth); -- -- tiles = new int[maxI][maxJ][tileWidth * tileWidth]; -- -- this.area = area; -- this.socket = socket; -- localHost = socket.getLocalAddress(); -- localPort = socket.getLocalPort(); -- this.remoteHost = remoteHost; -- this.remotePort = remotePort; -- this.encoder = new DefaultEncoder(); -- -- transmit = true; -- -- } -- catch (AWTException e) { -- e.printStackTrace(); -- } -- -- } -- -- public void start() { -- byte buf[] = new byte[1024]; -- final DatagramPacket p = new DatagramPacket(buf, 1024); -- -- int keyframe = 0; -- -- while (on) { -- if (transmit) { -- -- BufferedImage capture = robot.createScreenCapture(area); -- -- QuantizeFilter filter = new QuantizeFilter(); -- capture = filter.filter(capture, null); -- -- long trace = System.currentTimeMillis(); -- -- if (++keyframe > KEYFRAME) { -- keyframe = 0; -- } -- LOGGER.debug("KEYFRAME:" + keyframe); -- -- for (int i = 0; i < maxI; i++) { -- for (int j = 0; j < maxJ; j++) { -- -- final BufferedImage bufferedImage = capture.getSubimage(i * tileWidth, j * tileWidth, tileWidth, tileWidth); -- -- int pixels[] = new int[tileWidth * tileWidth]; -- -- PixelGrabber pg = new PixelGrabber(bufferedImage, 0, 0, tileWidth, tileWidth, pixels, 0, tileWidth); -- -- try { -- if (pg.grabPixels()) { -- -- if (keyframe == KEYFRAME || !Arrays.equals(tiles[i][j], pixels)) { -- -- ByteArrayOutputStream baos = encoder.encode(bufferedImage); -- -- if (baos != null) { -- -- try { -- -- Thread.sleep(1); -- -- baos.write(i); -- baos.write(j); -- -- byte[] bytesOut = baos.toByteArray(); -- -- if (bytesOut.length > 1000) -- LOGGER.error("Bytes out > 1000. Equals " + bytesOut.length); -- -- p.setData(bytesOut); -- p.setAddress(remoteHost); -- p.setPort(remotePort); -- -- try { -- socket.send(p); -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- -- tiles[i][j] = pixels; -- -- } -- catch (Exception e) { -- } -- -- } -- -- } -- -- } -- } -- catch (InterruptedException e) { -- e.printStackTrace(); -- } -- } -- } -- -- trace = (System.currentTimeMillis() - trace); -- LOGGER.debug("Loop Time:" + trace); -- -- if (trace < 500) { -- try { -- Thread.sleep(500 - trace); -- } -- catch (InterruptedException e) { -- e.printStackTrace(); -- } -- } -- } -- } -- } -- -- public void run() { -- start(); -- } -- -- /** -- * Set Transmit Enabled/Disabled -- * -- * @param transmit boolean Enabled/Disabled -- */ -- public void setTransmit(boolean transmit) { -- this.transmit = transmit; -- } -- -- /** -- * Get the encoder used to encode Images Tiles -- * -- * @return encoder -- */ -- public ImageEncoder getEncoder() { -- return encoder; -- } -- -- /** -- * Set the encoder used to encode Image Tiles -- * -- * @param encoder encoder -- */ -- public void setEncoder(ImageEncoder encoder) { -- this.encoder = encoder; -- } -- -- /** -- * Stops Transmitter -- */ -- public void stop() { -- this.transmit = false; -- this.on = false; -- socket.close(); -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java (working copy) -@@ -1,13 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.image.BufferedImage; --import java.io.ByteArrayOutputStream; -- --/** -- * Image Encoder Interface use this interface if you want to change the default encoder -- * -- * @author Thiago Rocha Camargo -- */ --public interface ImageEncoder { -- public ByteArrayOutputStream encode(BufferedImage bufferedImage); --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java (working copy) -@@ -1,223 +0,0 @@ --/* --Copyright 2006 Jerry Huxtable -- --Licensed under the Apache License, Version 2.0 (the "License"); --you may not use this file except in compliance with the License. --You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- --Unless required by applicable law or agreed to in writing, software --distributed under the License is distributed on an "AS IS" BASIS, --WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --See the License for the specific language governing permissions and --limitations under the License. --*/ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.*; --import java.util.Random; -- --/** -- * Some more useful math functions for image processing. -- * These are becoming obsolete as we move to Java2D. Use MiscComposite instead. -- */ --public class PixelUtils { -- -- public final static int REPLACE = 0; -- public final static int NORMAL = 1; -- public final static int MIN = 2; -- public final static int MAX = 3; -- public final static int ADD = 4; -- public final static int SUBTRACT = 5; -- public final static int DIFFERENCE = 6; -- public final static int MULTIPLY = 7; -- public final static int HUE = 8; -- public final static int SATURATION = 9; -- public final static int VALUE = 10; -- public final static int COLOR = 11; -- public final static int SCREEN = 12; -- public final static int AVERAGE = 13; -- public final static int OVERLAY = 14; -- public final static int CLEAR = 15; -- public final static int EXCHANGE = 16; -- public final static int DISSOLVE = 17; -- public final static int DST_IN = 18; -- public final static int ALPHA = 19; -- public final static int ALPHA_TO_GRAY = 20; -- -- private static Random randomGenerator = new Random(); -- -- /** -- * Clamp a value to the range 0..255 -- */ -- public static int clamp(int c) { -- if (c < 0) -- return 0; -- if (c > 255) -- return 255; -- return c; -- } -- -- public static int interpolate(int v1, int v2, float f) { -- return clamp((int)(v1+f*(v2-v1))); -- } -- -- public static int brightness(int rgb) { -- int r = (rgb >> 16) & 0xff; -- int g = (rgb >> 8) & 0xff; -- int b = rgb & 0xff; -- return (r+g+b)/3; -- } -- -- public static boolean nearColors(int rgb1, int rgb2, int tolerance) { -- int r1 = (rgb1 >> 16) & 0xff; -- int g1 = (rgb1 >> 8) & 0xff; -- int b1 = rgb1 & 0xff; -- int r2 = (rgb2 >> 16) & 0xff; -- int g2 = (rgb2 >> 8) & 0xff; -- int b2 = rgb2 & 0xff; -- return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance; -- } -- -- private final static float hsb1[] = new float[3];//FIXME-not thread safe -- private final static float hsb2[] = new float[3];//FIXME-not thread safe -- -- // Return rgb1 painted onto rgb2 -- public static int combinePixels(int rgb1, int rgb2, int op) { -- return combinePixels(rgb1, rgb2, op, 0xff); -- } -- -- public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha, int channelMask) { -- return (rgb2 & ~channelMask) | combinePixels(rgb1 & channelMask, rgb2, op, extraAlpha); -- } -- -- public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha) { -- if (op == REPLACE) -- return rgb1; -- int a1 = (rgb1 >> 24) & 0xff; -- int r1 = (rgb1 >> 16) & 0xff; -- int g1 = (rgb1 >> 8) & 0xff; -- int b1 = rgb1 & 0xff; -- int a2 = (rgb2 >> 24) & 0xff; -- int r2 = (rgb2 >> 16) & 0xff; -- int g2 = (rgb2 >> 8) & 0xff; -- int b2 = rgb2 & 0xff; -- -- switch (op) { -- case NORMAL: -- break; -- case MIN: -- r1 = Math.min(r1, r2); -- g1 = Math.min(g1, g2); -- b1 = Math.min(b1, b2); -- break; -- case MAX: -- r1 = Math.max(r1, r2); -- g1 = Math.max(g1, g2); -- b1 = Math.max(b1, b2); -- break; -- case ADD: -- r1 = clamp(r1+r2); -- g1 = clamp(g1+g2); -- b1 = clamp(b1+b2); -- break; -- case SUBTRACT: -- r1 = clamp(r2-r1); -- g1 = clamp(g2-g1); -- b1 = clamp(b2-b1); -- break; -- case DIFFERENCE: -- r1 = clamp(Math.abs(r1-r2)); -- g1 = clamp(Math.abs(g1-g2)); -- b1 = clamp(Math.abs(b1-b2)); -- break; -- case MULTIPLY: -- r1 = clamp(r1*r2/255); -- g1 = clamp(g1*g2/255); -- b1 = clamp(b1*b2/255); -- break; -- case DISSOLVE: -- if ((randomGenerator.nextInt() & 0xff) <= a1) { -- r1 = r2; -- g1 = g2; -- b1 = b2; -- } -- break; -- case AVERAGE: -- r1 = (r1+r2)/2; -- g1 = (g1+g2)/2; -- b1 = (b1+b2)/2; -- break; -- case HUE: -- case SATURATION: -- case VALUE: -- case COLOR: -- Color.RGBtoHSB(r1, g1, b1, hsb1); -- Color.RGBtoHSB(r2, g2, b2, hsb2); -- switch (op) { -- case HUE: -- hsb2[0] = hsb1[0]; -- break; -- case SATURATION: -- hsb2[1] = hsb1[1]; -- break; -- case VALUE: -- hsb2[2] = hsb1[2]; -- break; -- case COLOR: -- hsb2[0] = hsb1[0]; -- hsb2[1] = hsb1[1]; -- break; -- } -- rgb1 = Color.HSBtoRGB(hsb2[0], hsb2[1], hsb2[2]); -- r1 = (rgb1 >> 16) & 0xff; -- g1 = (rgb1 >> 8) & 0xff; -- b1 = rgb1 & 0xff; -- break; -- case SCREEN: -- r1 = 255 - ((255 - r1) * (255 - r2)) / 255; -- g1 = 255 - ((255 - g1) * (255 - g2)) / 255; -- b1 = 255 - ((255 - b1) * (255 - b2)) / 255; -- break; -- case OVERLAY: -- int m, s; -- s = 255 - ((255 - r1) * (255 - r2)) / 255; -- m = r1 * r2 / 255; -- r1 = (s * r1 + m * (255 - r1)) / 255; -- s = 255 - ((255 - g1) * (255 - g2)) / 255; -- m = g1 * g2 / 255; -- g1 = (s * g1 + m * (255 - g1)) / 255; -- s = 255 - ((255 - b1) * (255 - b2)) / 255; -- m = b1 * b2 / 255; -- b1 = (s * b1 + m * (255 - b1)) / 255; -- break; -- case CLEAR: -- r1 = g1 = b1 = 0xff; -- break; -- case DST_IN: -- r1 = clamp((r2*a1)/255); -- g1 = clamp((g2*a1)/255); -- b1 = clamp((b2*a1)/255); -- a1 = clamp((a2*a1)/255); -- return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; -- case ALPHA: -- a1 = a1*a2/255; -- return (a1 << 24) | (r2 << 16) | (g2 << 8) | b2; -- case ALPHA_TO_GRAY: -- int na = 255-a1; -- return (a1 << 24) | (na << 16) | (na << 8) | na; -- } -- if (extraAlpha != 0xff || a1 != 0xff) { -- a1 = a1*extraAlpha/255; -- int a3 = (255-a1)*a2/255; -- r1 = clamp((r1*a1+r2*a3)/255); -- g1 = clamp((g1*a1+g2*a3)/255); -- b1 = clamp((b1*a1+b2*a3)/255); -- a1 = clamp(a1+a3); -- } -- return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; -- } -- --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java (working copy) -@@ -1,53 +0,0 @@ --/* --Copyright 2006 Jerry Huxtable -- --Licensed under the Apache License, Version 2.0 (the "License"); --you may not use this file except in compliance with the License. --You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- --Unless required by applicable law or agreed to in writing, software --distributed under the License is distributed on an "AS IS" BASIS, --WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --See the License for the specific language governing permissions and --limitations under the License. --*/ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --/** -- * The interface for an image quantizer. The addColor method is called (repeatedly -- * if necessary) with all the image pixels. A color table can then be returned by -- * calling the buildColorTable method. -- */ --public interface Quantizer { -- /** -- * Initialize the quantizer. This should be called before adding any pixels. -- * @param numColors the number of colors we're quantizing to. -- */ -- public void setup(int numColors); -- -- /** -- * Add pixels to the quantizer. -- * @param pixels the array of ARGB pixels -- * @param offset the offset into the array -- * @param count the count of pixels -- */ -- public void addPixels(int[] pixels, int offset, int count); -- -- /** -- * Build a color table from the added pixels. -- * @return an array of ARGB pixels representing a color table -- */ -- public int[] buildColorTable(); -- -- /** -- * Using the previously-built color table, return the index into that table for a pixel. -- * This is guaranteed to return a valid index - returning the index of a color closer -- * to that requested if necessary. -- * @param rgb the pixel to find -- * @return the pixel's index in the color table -- */ -- public int getIndexForColor(int rgb); --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java (working copy) -@@ -1,24 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import javax.imageio.ImageIO; --import java.awt.image.BufferedImage; --import java.io.ByteArrayOutputStream; --import java.io.IOException; -- --/** -- * Implements a default PNG Encoder -- */ --public class DefaultEncoder implements ImageEncoder{ -- -- public ByteArrayOutputStream encode(BufferedImage bufferedImage) { -- ByteArrayOutputStream baos = new ByteArrayOutputStream(); -- try { -- ImageIO.write(bufferedImage, "png", baos); -- } -- catch (IOException e) { -- e.printStackTrace(); -- baos = null; -- } -- return baos; -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java (working copy) -@@ -1,178 +0,0 @@ --/* --Copyright 2006 Jerry Huxtable -- --Licensed under the Apache License, Version 2.0 (the "License"); --you may not use this file except in compliance with the License. --You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- --Unless required by applicable law or agreed to in writing, software --distributed under the License is distributed on an "AS IS" BASIS, --WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --See the License for the specific language governing permissions and --limitations under the License. --*/ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.*; -- --/** -- * A filter which quantizes an image to a set number of colors - useful for producing -- * images which are to be encoded using an index color model. The filter can perform -- * Floyd-Steinberg error-diffusion dithering if required. At present, the quantization -- * is done using an octtree algorithm but I eventually hope to add more quantization -- * methods such as median cut. Note: at present, the filter produces an image which -- * uses the RGB color model (because the application it was written for required it). -- * I hope to extend it to produce an IndexColorModel by request. -- */ --public class QuantizeFilter extends WholeImageFilter { -- -- /** -- * Floyd-Steinberg dithering matrix. -- */ -- protected final static int[] matrix = { -- 0, 0, 0, -- 0, 0, 7, -- 3, 5, 1, -- }; -- private int sum = 3+5+7+1; -- -- private boolean dither; -- private int numColors = 256; -- private boolean serpentine = true; -- -- /** -- * Set the number of colors to quantize to. -- * @param numColors the number of colors. The default is 256. -- */ -- public void setNumColors(int numColors) { -- this.numColors = Math.min(Math.max(numColors, 8), 256); -- } -- -- /** -- * Get the number of colors to quantize to. -- * @return the number of colors. -- */ -- public int getNumColors() { -- return numColors; -- } -- -- /** -- * Set whether to use dithering or not. If not, the image is posterized. -- * @param dither true to use dithering -- */ -- public void setDither(boolean dither) { -- this.dither = dither; -- } -- -- /** -- * Return the dithering setting -- * @return the current setting -- */ -- public boolean getDither() { -- return dither; -- } -- -- /** -- * Set whether to use a serpentine pattern for return or not. This can reduce 'avalanche' artifacts in the output. -- * @param serpentine true to use serpentine pattern -- */ -- public void setSerpentine(boolean serpentine) { -- this.serpentine = serpentine; -- } -- -- /** -- * Return the serpentine setting -- * @return the current setting -- */ -- public boolean getSerpentine() { -- return serpentine; -- } -- -- public void quantize(int[] inPixels, int[] outPixels, int width, int height, int numColors, boolean dither, boolean serpentine) { -- int count = width*height; -- Quantizer quantizer = new OctTreeQuantizer(); -- quantizer.setup(numColors); -- quantizer.addPixels(inPixels, 0, count); -- int[] table = quantizer.buildColorTable(); -- -- if (!dither) { -- for (int i = 0; i < count; i++) -- outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])]; -- } else { -- int index = 0; -- for (int y = 0; y < height; y++) { -- boolean reverse = serpentine && (y & 1) == 1; -- int direction; -- if (reverse) { -- index = y*width+width-1; -- direction = -1; -- } else { -- index = y*width; -- direction = 1; -- } -- for (int x = 0; x < width; x++) { -- int rgb1 = inPixels[index]; -- int rgb2 = table[quantizer.getIndexForColor(rgb1)]; -- -- outPixels[index] = rgb2; -- -- int r1 = (rgb1 >> 16) & 0xff; -- int g1 = (rgb1 >> 8) & 0xff; -- int b1 = rgb1 & 0xff; -- -- int r2 = (rgb2 >> 16) & 0xff; -- int g2 = (rgb2 >> 8) & 0xff; -- int b2 = rgb2 & 0xff; -- -- int er = r1-r2; -- int eg = g1-g2; -- int eb = b1-b2; -- -- for (int i = -1; i <= 1; i++) { -- int iy = i+y; -- if (0 <= iy && iy < height) { -- for (int j = -1; j <= 1; j++) { -- int jx = j+x; -- if (0 <= jx && jx < width) { -- int w; -- if (reverse) -- w = matrix[(i+1)*3-j+1]; -- else -- w = matrix[(i+1)*3+j+1]; -- if (w != 0) { -- int k = reverse ? index - j : index + j; -- rgb1 = inPixels[k]; -- r1 = (rgb1 >> 16) & 0xff; -- g1 = (rgb1 >> 8) & 0xff; -- b1 = rgb1 & 0xff; -- r1 += er * w/sum; -- g1 += eg * w/sum; -- b1 += eb * w/sum; -- inPixels[k] = (PixelUtils.clamp(r1) << 16) | (PixelUtils.clamp(g1) << 8) | PixelUtils.clamp(b1); -- } -- } -- } -- } -- } -- index += direction; -- } -- } -- } -- } -- -- protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { -- int[] outPixels = new int[width*height]; -- -- quantize(inPixels, outPixels, width, height, numColors, dither, serpentine); -- -- return outPixels; -- } -- -- public String toString() { -- return "Colors/Quantize..."; -- } -- --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java (working copy) -@@ -1,150 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.*; --import java.awt.image.BufferedImage; --import java.io.ByteArrayInputStream; --import java.io.IOException; --import java.net.DatagramPacket; --import java.net.DatagramSocket; --import java.net.InetAddress; --import java.net.SocketException; -- --/** -- * UDP Image Receiver. -- * It uses PNG Tiles into UDP packets. -- * -- * @author Thiago Rocha Camargo -- */ --public class ImageReceiver extends Canvas { -- -- private boolean on = true; -- private DatagramSocket socket; -- private BufferedImage tiles[][]; -- private static final int tileWidth = ImageTransmitter.tileWidth; -- private InetAddress localHost; -- private InetAddress remoteHost; -- private int localPort; -- private int remotePort; -- private ImageDecoder decoder; -- -- public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) { -- tiles = new BufferedImage[width][height]; -- -- try { -- -- socket = new DatagramSocket(localPort); -- localHost = socket.getLocalAddress(); -- this.remoteHost = remoteHost; -- this.remotePort = remotePort; -- this.localPort = localPort; -- this.decoder = new DefaultDecoder(); -- -- new Thread(new Runnable() { -- public void run() { -- byte buf[] = new byte[1024]; -- DatagramPacket p = new DatagramPacket(buf, 1024); -- try { -- while (on) { -- socket.receive(p); -- -- int length = p.getLength(); -- -- BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2)); -- -- if (bufferedImage != null) { -- -- int x = p.getData()[length - 2]; -- int y = p.getData()[length - 1]; -- -- drawTile(x, y, bufferedImage); -- -- } -- -- } -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- } -- }).start(); -- -- new Thread(new Runnable() { -- public void run() { -- byte buf[] = new byte[1024]; -- DatagramPacket p = new DatagramPacket(buf, 1024); -- try { -- while (on) { -- -- p.setAddress(remoteHost); -- p.setPort(remotePort); -- socket.send(p); -- -- try { -- Thread.sleep(1000); -- } -- catch (InterruptedException e) { -- e.printStackTrace(); -- } -- -- } -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- } -- }).start(); -- -- } -- catch (SocketException e) { -- e.printStackTrace(); -- } -- this.setSize(width, height); -- } -- -- public InetAddress getLocalHost() { -- return localHost; -- } -- -- public InetAddress getRemoteHost() { -- return remoteHost; -- } -- -- public int getLocalPort() { -- return localPort; -- } -- -- public int getRemotePort() { -- return remotePort; -- } -- -- public DatagramSocket getDatagramSocket() { -- return socket; -- } -- -- public void drawTile(int x, int y, BufferedImage bufferedImage) { -- tiles[x][y] = bufferedImage; -- //repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth); -- this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this); -- } -- -- public void paint(Graphics g) { -- for (int i = 0; i < tiles.length; i++) { -- for (int j = 0; j < tiles[0].length; j++) { -- g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this); -- } -- } -- } -- -- public ImageDecoder getDecoder() { -- return decoder; -- } -- -- public void setDecoder(ImageDecoder decoder) { -- this.decoder = decoder; -- } -- -- public void stop(){ -- this.on=false; -- socket.close(); -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java (working copy) -@@ -1,86 +0,0 @@ --/* --Copyright 2006 Jerry Huxtable -- --Licensed under the Apache License, Version 2.0 (the "License"); --you may not use this file except in compliance with the License. --You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- --Unless required by applicable law or agreed to in writing, software --distributed under the License is distributed on an "AS IS" BASIS, --WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --See the License for the specific language governing permissions and --limitations under the License. --*/ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.*; --import java.awt.image.BufferedImage; --import java.awt.image.ColorModel; --import java.awt.image.WritableRaster; -- --/** -- * A filter which acts as a superclass for filters which need to have the whole image in memory -- * to do their stuff. -- */ --public abstract class WholeImageFilter extends AbstractBufferedImageOp { -- -- /** -- * The output image bounds. -- */ -- protected Rectangle transformedSpace; -- -- /** -- * The input image bounds. -- */ -- protected Rectangle originalSpace; -- -- /** -- * Construct a WholeImageFilter. -- */ -- public WholeImageFilter() { -- } -- -- public BufferedImage filter( BufferedImage src, BufferedImage dst ) { -- int width = src.getWidth(); -- int height = src.getHeight(); -- int type = src.getType(); -- WritableRaster srcRaster = src.getRaster(); -- -- originalSpace = new Rectangle(0, 0, width, height); -- transformedSpace = new Rectangle(0, 0, width, height); -- transformSpace(transformedSpace); -- -- if ( dst == null ) { -- ColorModel dstCM = src.getColorModel(); -- dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null); -- } -- WritableRaster dstRaster = dst.getRaster(); -- -- int[] inPixels = getRGB( src, 0, 0, width, height, null ); -- inPixels = filterPixels( width, height, inPixels, transformedSpace ); -- setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels ); -- -- return dst; -- } -- -- /** -- * Calculate output bounds for given input bounds. -- * @param rect input and output rectangle -- */ -- protected void transformSpace(Rectangle rect) { -- } -- -- /** -- * Actually filter the pixels. -- * @param width the image width -- * @param height the image height -- * @param inPixels the image pixels -- * @param transformedSpace the output bounds -- * @return the output pixels -- */ -- protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ); --} -- -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java (working copy) -@@ -1,98 +0,0 @@ --/* --Copyright 2006 Jerry Huxtable -- --Licensed under the Apache License, Version 2.0 (the "License"); --you may not use this file except in compliance with the License. --You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- --Unless required by applicable law or agreed to in writing, software --distributed under the License is distributed on an "AS IS" BASIS, --WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --See the License for the specific language governing permissions and --limitations under the License. --*/ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.*; --import java.awt.geom.Point2D; --import java.awt.geom.Rectangle2D; --import java.awt.image.BufferedImage; --import java.awt.image.BufferedImageOp; --import java.awt.image.ColorModel; -- --/** -- * A convenience class which implements those methods of BufferedImageOp which are rarely changed. -- */ --public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable { -- -- public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) { -- if ( dstCM == null ) -- dstCM = src.getColorModel(); -- return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null); -- } -- -- public Rectangle2D getBounds2D( BufferedImage src ) { -- return new Rectangle(0, 0, src.getWidth(), src.getHeight()); -- } -- -- public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) { -- if ( dstPt == null ) -- dstPt = new Point2D.Double(); -- dstPt.setLocation( srcPt.getX(), srcPt.getY() ); -- return dstPt; -- } -- -- public RenderingHints getRenderingHints() { -- return null; -- } -- -- /** -- * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance -- * penalty of BufferedImage.getRGB unmanaging the image. -- * @param image a BufferedImage object -- * @param x the left edge of the pixel block -- * @param y the right edge of the pixel block -- * @param width the width of the pixel arry -- * @param height the height of the pixel arry -- * @param pixels the array to hold the returned pixels. May be null. -- * @return the pixels -- * @see #setRGB -- */ -- public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) { -- int type = image.getType(); -- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB ) -- return (int [])image.getRaster().getDataElements( x, y, width, height, pixels ); -- return image.getRGB( x, y, width, height, pixels, 0, width ); -- } -- -- /** -- * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance -- * penalty of BufferedImage.setRGB unmanaging the image. -- * @param image a BufferedImage object -- * @param x the left edge of the pixel block -- * @param y the right edge of the pixel block -- * @param width the width of the pixel arry -- * @param height the height of the pixel arry -- * @param pixels the array of pixels to set -- * @see #getRGB -- */ -- public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) { -- int type = image.getType(); -- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB ) -- image.getRaster().setDataElements( x, y, width, height, pixels ); -- else -- image.setRGB( x, y, width, height, pixels, 0, width ); -- } -- -- public Object clone() { -- try { -- return super.clone(); -- } -- catch ( CloneNotSupportedException e ) { -- return null; -- } -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java (working copy) -@@ -1,15 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.awt.image.BufferedImage; --import java.io.ByteArrayInputStream; --import java.io.IOException; -- --/** -- * Image Decoder Interface use this interface if you want to change the default decoder -- * -- * @author Thiago Rocha Camargo -- */ --public interface ImageDecoder { -- -- public BufferedImage decode(ByteArrayInputStream stream) throws IOException; --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java (working copy) -@@ -1,287 +0,0 @@ --/* --Copyright 2006 Jerry Huxtable -- --Licensed under the Apache License, Version 2.0 (the "License"); --you may not use this file except in compliance with the License. --You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- --Unless required by applicable law or agreed to in writing, software --distributed under the License is distributed on an "AS IS" BASIS, --WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --See the License for the specific language governing permissions and --limitations under the License. --*/ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import java.io.PrintStream; --import java.util.Vector; -- --import org.jivesoftware.smackx.jingle.SmackLogger; -- --/** -- * An image Quantizer based on the Octree algorithm. This is a very basic implementation -- * at present and could be much improved by picking the nodes to reduce more carefully -- * (i.e. not completely at random) when I get the time. -- */ --public class OctTreeQuantizer implements Quantizer { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(OctTreeQuantizer.class); -- -- /** -- * The greatest depth the tree is allowed to reach -- */ -- final static int MAX_LEVEL = 5; -- -- /** -- * An Octtree node. -- */ -- class OctTreeNode { -- int children; -- int level; -- OctTreeNode parent; -- OctTreeNode leaf[] = new OctTreeNode[8]; -- boolean isLeaf; -- int count; -- int totalRed; -- int totalGreen; -- int totalBlue; -- int index; -- -- /** -- * A debugging method which prints the tree out. -- */ -- public void list(PrintStream s, int level) { -- String indentStr = ""; -- for (int i = 0; i < level; i++) -- indentStr += " "; -- if (count == 0) -- LOGGER.debug(indentStr + index + ": count=" + count); -- else -- LOGGER.debug(indentStr + index + ": count=" + count + " red=" + (totalRed/count) + " green=" + (totalGreen / count) + " blue=" + (totalBlue / count)); -- for (int i = 0; i < 8; i++) -- if (leaf[i] != null) -- leaf[i].list(s, level+2); -- } -- } -- -- private int nodes = 0; -- private OctTreeNode root; -- private int reduceColors; -- private int maximumColors; -- private int colors = 0; -- private Vector[] colorList; -- -- public OctTreeQuantizer() { -- setup(256); -- colorList = new Vector[MAX_LEVEL+1]; -- for (int i = 0; i < MAX_LEVEL+1; i++) -- colorList[i] = new Vector(); -- root = new OctTreeNode(); -- } -- -- /** -- * Initialize the quantizer. This should be called before adding any pixels. -- * @param numColors the number of colors we're quantizing to. -- */ -- public void setup(int numColors) { -- maximumColors = numColors; -- reduceColors = Math.max(512, numColors * 2); -- } -- -- /** -- * Add pixels to the quantizer. -- * @param pixels the array of ARGB pixels -- * @param offset the offset into the array -- * @param count the count of pixels -- */ -- public void addPixels(int[] pixels, int offset, int count) { -- for (int i = 0; i < count; i++) { -- insertColor(pixels[i+offset]); -- if (colors > reduceColors) -- reduceTree(reduceColors); -- } -- } -- -- /** -- * Get the color table index for a color. -- * @param rgb the color -- * @return the index -- */ -- public int getIndexForColor(int rgb) { -- int red = (rgb >> 16) & 0xff; -- int green = (rgb >> 8) & 0xff; -- int blue = rgb & 0xff; -- -- OctTreeNode node = root; -- -- for (int level = 0; level <= MAX_LEVEL; level++) { -- OctTreeNode child; -- int bit = 0x80 >> level; -- -- int index = 0; -- if ((red & bit) != 0) -- index += 4; -- if ((green & bit) != 0) -- index += 2; -- if ((blue & bit) != 0) -- index += 1; -- -- child = node.leaf[index]; -- -- if (child == null) -- return node.index; -- else if (child.isLeaf) -- return child.index; -- else -- node = child; -- } -- LOGGER.debug("getIndexForColor failed"); -- return 0; -- } -- -- private void insertColor(int rgb) { -- int red = (rgb >> 16) & 0xff; -- int green = (rgb >> 8) & 0xff; -- int blue = rgb & 0xff; -- -- OctTreeNode node = root; -- --// LOGGER.debug("insertColor="+Integer.toHexString(rgb)); -- for (int level = 0; level <= MAX_LEVEL; level++) { -- OctTreeNode child; -- int bit = 0x80 >> level; -- -- int index = 0; -- if ((red & bit) != 0) -- index += 4; -- if ((green & bit) != 0) -- index += 2; -- if ((blue & bit) != 0) -- index += 1; -- -- child = node.leaf[index]; -- -- if (child == null) { -- node.children++; -- -- child = new OctTreeNode(); -- child.parent = node; -- node.leaf[index] = child; -- node.isLeaf = false; -- nodes++; -- colorList[level].addElement(child); -- -- if (level == MAX_LEVEL) { -- child.isLeaf = true; -- child.count = 1; -- child.totalRed = red; -- child.totalGreen = green; -- child.totalBlue = blue; -- child.level = level; -- colors++; -- return; -- } -- -- node = child; -- } else if (child.isLeaf) { -- child.count++; -- child.totalRed += red; -- child.totalGreen += green; -- child.totalBlue += blue; -- return; -- } else -- node = child; -- } -- LOGGER.debug("insertColor failed"); -- } -- -- private void reduceTree(int numColors) { -- for (int level = MAX_LEVEL-1; level >= 0; level--) { -- Vector v = colorList[level]; -- if (v != null && v.size() > 0) { -- for (int j = 0; j < v.size(); j++) { -- OctTreeNode node = (OctTreeNode)v.elementAt(j); -- if (node.children > 0) { -- for (int i = 0; i < 8; i++) { -- OctTreeNode child = node.leaf[i]; -- if (child != null) { -- if (!child.isLeaf) -- LOGGER.debug("not a leaf!"); -- node.count += child.count; -- node.totalRed += child.totalRed; -- node.totalGreen += child.totalGreen; -- node.totalBlue += child.totalBlue; -- node.leaf[i] = null; -- node.children--; -- colors--; -- nodes--; -- colorList[level+1].removeElement(child); -- } -- } -- node.isLeaf = true; -- colors++; -- if (colors <= numColors) -- return; -- } -- } -- } -- } -- -- LOGGER.debug("Unable to reduce the OctTree"); -- } -- -- /** -- * Build the color table. -- * @return the color table -- */ -- public int[] buildColorTable() { -- int[] table = new int[colors]; -- buildColorTable(root, table, 0); -- return table; -- } -- -- /** -- * A quick way to use the quantizer. Just create a table the right size and pass in the pixels. -- * @param inPixels the input colors -- * @param table the output color table -- */ -- public void buildColorTable(int[] inPixels, int[] table) { -- int count = inPixels.length; -- maximumColors = table.length; -- for (int i = 0; i < count; i++) { -- insertColor(inPixels[i]); -- if (colors > reduceColors) -- reduceTree(reduceColors); -- } -- if (colors > maximumColors) -- reduceTree(maximumColors); -- buildColorTable(root, table, 0); -- } -- -- private int buildColorTable(OctTreeNode node, int[] table, int index) { -- if (colors > maximumColors) -- reduceTree(maximumColors); -- -- if (node.isLeaf) { -- int count = node.count; -- table[index] = 0xff000000 | -- ((node.totalRed/count) << 16) | -- ((node.totalGreen/count) << 8) | -- node.totalBlue/count; -- node.index = index++; -- } else { -- for (int i = 0; i < 8; i++) { -- if (node.leaf[i] != null) { -- node.index = index; -- index = buildColorTable(node.leaf[i], table, index); -- } -- } -- } -- return index; -- } -- --} -- -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java (working copy) -@@ -1,16 +0,0 @@ --package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api; -- --import javax.imageio.ImageIO; --import java.awt.image.BufferedImage; --import java.io.ByteArrayInputStream; --import java.io.IOException; -- --/** -- * Implements a default PNG decoder. -- */ --public class DefaultDecoder implements ImageDecoder { -- -- public BufferedImage decode(ByteArrayInputStream stream) throws IOException { -- return ImageIO.read(stream); -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java (working copy) -@@ -1,115 +0,0 @@ --/** -- * $RCSfile: ScreenShareMediaManager.java,v $ -- * $Revision: 1.3 $ -- * $Date: 25/12/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.sshare; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.media.JingleMediaManager; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder; --import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder; --import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --import java.util.ArrayList; --import java.util.List; -- --/** -- * Implements a JingleMediaManager for ScreenSharing. -- * It currently uses an Audio payload Type. Which needs to be fixed in the next version. -- * -- * @author Thiago Camargo -- */ -- --public class ScreenShareMediaManager extends JingleMediaManager { -- -- public static final String MEDIA_NAME = "ScreenShare"; -- -- private List payloads = new ArrayList(); -- -- private ImageDecoder decoder = null; -- private ImageEncoder encoder = null; -- -- public ScreenShareMediaManager(JingleTransportManager transportManager) { -- super(transportManager); -- setupPayloads(); -- } -- -- /** -- * Setup API supported Payloads -- */ -- private void setupPayloads() { -- payloads.add(new PayloadType.Audio(30, "sshare")); -- } -- -- /** -- * Return all supported Payloads for this Manager. -- * -- * @return The Payload List -- */ -- public List getPayloads() { -- return payloads; -- } -- -- /** -- * Returns a new JingleMediaSession -- * -- * @param payloadType payloadType -- * @param remote remote Candidate -- * @param local local Candidate -- * @return JingleMediaSession JingleMediaSession -- */ -- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) { -- ScreenShareSession session = null; -- session = new ScreenShareSession(payloadType, remote, local, "Screen", jingleSession); -- if (encoder != null) { -- session.setEncoder(encoder); -- } -- if (decoder != null) { -- session.setDecoder(decoder); -- } -- return session; -- } -- -- public PayloadType getPreferredPayloadType() { -- return super.getPreferredPayloadType(); -- } -- -- public ImageDecoder getDecoder() { -- return decoder; -- } -- -- public void setDecoder(ImageDecoder decoder) { -- this.decoder = decoder; -- } -- -- public ImageEncoder getEncoder() { -- return encoder; -- } -- -- public void setEncoder(ImageEncoder encoder) { -- this.encoder = encoder; -- } -- -- public String getName() { -- return MEDIA_NAME; -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java (working copy) -@@ -1,106 +0,0 @@ --/** -- * $RCSfile: MultiMediaManager.java,v $ -- * $Revision: 1.3 $ -- * $Date: 25/12/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.multi; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.media.JingleMediaManager; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --import java.util.ArrayList; --import java.util.List; -- --/** -- * Implements a MultiMediaManager using other JingleMediaManager implementations. -- * It supports every Codecs that JingleMediaManagers added has. -- * -- * @author Thiago Camargo -- */ -- --public class MultiMediaManager extends JingleMediaManager { -- -- public static final String MEDIA_NAME = "Multi"; -- -- private List managers = new ArrayList(); -- -- private PayloadType preferredPayloadType = null; -- -- public MultiMediaManager(JingleTransportManager transportManager) { -- super(transportManager); -- } -- -- public void addMediaManager(JingleMediaManager manager) { -- managers.add(manager); -- } -- -- public void removeMediaManager(JingleMediaManager manager) { -- managers.remove(manager); -- } -- -- /** -- * Return all supported Payloads for this Manager. -- * -- * @return The Payload List -- */ -- public List getPayloads() { -- List list = new ArrayList(); -- if (preferredPayloadType != null) list.add(preferredPayloadType); -- for (JingleMediaManager manager : managers) { -- for (PayloadType payloadType : manager.getPayloads()) { -- if (!list.contains(payloadType) && !payloadType.equals(preferredPayloadType)) -- list.add(payloadType); -- } -- } -- return list; -- } -- -- /** -- * Returns a new JingleMediaSession -- * -- * @param payloadType payloadType -- * @param remote remote Candidate -- * @param local local Candidate -- * @return JingleMediaSession JingleMediaSession -- */ -- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) { -- for (JingleMediaManager manager : managers) { -- if (manager.getPayloads().contains(payloadType)) { -- return manager.createMediaSession(payloadType, remote, local, jingleSession); -- } -- } -- return null; -- } -- -- public PayloadType getPreferredPayloadType() { -- if (preferredPayloadType != null) return preferredPayloadType; -- return super.getPreferredPayloadType(); -- } -- -- public void setPreferredPayloadType(PayloadType preferredPayloadType) { -- this.preferredPayloadType = preferredPayloadType; -- } -- -- public String getName() { -- return MEDIA_NAME; -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java (working copy) -@@ -1,165 +0,0 @@ --/** -- * $RCSfile: AudioMediaSession.java,v $ -- * $Revision: 1.1 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.jmf; -- --import java.io.IOException; --import java.net.ServerSocket; -- --import javax.media.MediaLocator; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --/** -- * This Class implements a complete JingleMediaSession. -- * It sould be used to transmit and receive audio captured from the Mic. -- * This Class should be automaticly controlled by JingleSession. -- * But you could also use in any VOIP application. -- * For better NAT Traversal support this implementation don't support only receive or only transmit. -- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit() -- * -- * @author Thiago Camargo -- */ --public class AudioMediaSession extends JingleMediaSession { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class); -- -- private AudioChannel audioChannel; -- -- /** -- * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates -- * -- * @param payloadType Payload of the jmf -- * @param remote the remote information. The candidate that the jmf will be sent to. -- * @param local the local information. The candidate that will receive the jmf -- * @param locator media locator -- */ -- public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, -- final TransportCandidate local, String locator, JingleSession jingleSession) { -- super(payloadType, remote, local, locator==null?"dsound://":locator,jingleSession); -- initialize(); -- } -- -- /** -- * Initialize the Audio Channel to make it able to send and receive audio -- */ -- public void initialize() { -- -- String ip; -- String localIp; -- int localPort; -- int remotePort; -- -- if (this.getLocal().getSymmetric() != null) { -- ip = this.getLocal().getIp(); -- localIp = this.getLocal().getLocalIp(); -- localPort = getFreePort(); -- remotePort = this.getLocal().getSymmetric().getPort(); -- -- LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort); -- -- } -- else { -- ip = this.getRemote().getIp(); -- localIp = this.getLocal().getLocalIp(); -- localPort = this.getLocal().getPort(); -- remotePort = this.getRemote().getPort(); -- } -- -- audioChannel = new AudioChannel(new MediaLocator(this.getMediaLocator()), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType()),this); -- } -- -- /** -- * Starts transmission and for NAT Traversal reasons start receiving also. -- */ -- public void startTrasmit() { -- audioChannel.start(); -- } -- -- /** -- * Set transmit activity. If the active is true, the instance should trasmit. -- * If it is set to false, the instance should pause transmit. -- * -- * @param active active state -- */ -- public void setTrasmit(boolean active) { -- audioChannel.setTrasmit(active); -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void startReceive() { -- // Do nothing -- } -- -- /** -- * Stops transmission and for NAT Traversal reasons stop receiving also. -- */ -- public void stopTrasmit() { -- if (audioChannel != null) -- audioChannel.stop(); -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void stopReceive() { -- // Do nothing -- } -- -- /** -- * Obtain a free port we can use. -- * -- * @return A free port number. -- */ -- protected int getFreePort() { -- ServerSocket ss; -- int freePort = 0; -- -- for (int i = 0; i < 10; i++) { -- freePort = (int) (10000 + Math.round(Math.random() * 10000)); -- freePort = freePort % 2 == 0 ? freePort : freePort + 1; -- try { -- ss = new ServerSocket(freePort); -- freePort = ss.getLocalPort(); -- ss.close(); -- return freePort; -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- } -- try { -- ss = new ServerSocket(0); -- freePort = ss.getLocalPort(); -- ss.close(); -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- return freePort; -- } -- --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java (working copy) -@@ -1,171 +0,0 @@ --/** -- * $RCSfile: AudioReceiver.java,v $ -- * $Revision: 1.1 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.jmf; -- --import javax.media.ControllerErrorEvent; --import javax.media.ControllerEvent; --import javax.media.ControllerListener; --import javax.media.Player; --import javax.media.RealizeCompleteEvent; --import javax.media.protocol.DataSource; --import javax.media.rtp.Participant; --import javax.media.rtp.RTPControl; --import javax.media.rtp.ReceiveStream; --import javax.media.rtp.ReceiveStreamListener; --import javax.media.rtp.SessionListener; --import javax.media.rtp.event.ByeEvent; --import javax.media.rtp.event.NewParticipantEvent; --import javax.media.rtp.event.NewReceiveStreamEvent; --import javax.media.rtp.event.ReceiveStreamEvent; --import javax.media.rtp.event.RemotePayloadChangeEvent; --import javax.media.rtp.event.SessionEvent; --import javax.media.rtp.event.StreamMappedEvent; -- --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; -- --/** -- * This class implements receive methods and listeners to be used in AudioChannel -- * -- * @author Thiago Camargo -- */ --public class AudioReceiver implements ReceiveStreamListener, SessionListener, -- ControllerListener { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioReceiver.class); -- -- boolean dataReceived = false; -- -- Object dataSync; -- JingleMediaSession jingleMediaSession; -- -- public AudioReceiver(final Object dataSync, final JingleMediaSession jingleMediaSession) { -- this.dataSync = dataSync; -- this.jingleMediaSession = jingleMediaSession; -- } -- -- /** -- * JingleSessionListener. -- */ -- public synchronized void update(SessionEvent evt) { -- if (evt instanceof NewParticipantEvent) { -- Participant p = ((NewParticipantEvent) evt).getParticipant(); -- LOGGER.error(" - A new participant had just joined: " + p.getCNAME()); -- } -- } -- -- /** -- * ReceiveStreamListener -- */ -- public synchronized void update(ReceiveStreamEvent evt) { -- -- Participant participant = evt.getParticipant(); // could be null. -- ReceiveStream stream = evt.getReceiveStream(); // could be null. -- -- if (evt instanceof RemotePayloadChangeEvent) { -- LOGGER.error(" - Received an RTP PayloadChangeEvent."); -- LOGGER.error("Sorry, cannot handle payload change."); -- -- } -- else if (evt instanceof NewReceiveStreamEvent) { -- -- try { -- stream = evt.getReceiveStream(); -- DataSource ds = stream.getDataSource(); -- -- // Find out the formats. -- RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); -- if (ctl != null) { -- LOGGER.error(" - Recevied new RTP stream: " + ctl.getFormat()); -- } -- else -- LOGGER.error(" - Recevied new RTP stream"); -- -- if (participant == null) -- LOGGER.error(" The sender of this stream had yet to be identified."); -- else { -- LOGGER.error(" The stream comes from: " + participant.getCNAME()); -- } -- -- // create a player by passing datasource to the Media Manager -- Player p = javax.media.Manager.createPlayer(ds); -- if (p == null) -- return; -- -- p.addControllerListener(this); -- p.realize(); -- jingleMediaSession.mediaReceived(participant != null ? participant.getCNAME() : ""); -- -- // Notify intialize() that a new stream had arrived. -- synchronized (dataSync) { -- dataReceived = true; -- dataSync.notifyAll(); -- } -- -- } -- catch (Exception e) { -- LOGGER.error("NewReceiveStreamEvent exception " + e.getMessage()); -- return; -- } -- -- } -- else if (evt instanceof StreamMappedEvent) { -- -- if (stream != null && stream.getDataSource() != null) { -- DataSource ds = stream.getDataSource(); -- // Find out the formats. -- RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); -- LOGGER.error(" - The previously unidentified stream "); -- if (ctl != null) -- LOGGER.error(" " + ctl.getFormat()); -- LOGGER.error(" had now been identified as sent by: " + participant.getCNAME()); -- } -- } -- else if (evt instanceof ByeEvent) { -- -- LOGGER.error(" - Got \"bye\" from: " + participant.getCNAME()); -- -- } -- -- } -- -- /** -- * ControllerListener for the Players. -- */ -- public synchronized void controllerUpdate(ControllerEvent ce) { -- -- Player p = (Player) ce.getSourceController(); -- -- if (p == null) -- return; -- -- // Get this when the internal players are realized. -- if (ce instanceof RealizeCompleteEvent) { -- p.start(); -- } -- -- if (ce instanceof ControllerErrorEvent) { -- p.removeControllerListener(this); -- LOGGER.error("Receiver internal error: " + ce); -- } -- -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java (working copy) -@@ -1,170 +0,0 @@ --/** -- * $RCSfile: JmfMediaManager.java,v $ -- * $Revision: 1.3 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.jmf; -- --import java.io.File; --import java.io.IOException; --import java.util.ArrayList; --import java.util.List; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaManager; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.mediaimpl.JMFInit; --import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --/** -- * Implements a jingleMediaManager using JMF based API. -- * It supports GSM and G723 codecs. -- * This API only currently works on windows and Mac. -- * -- * @author Thiago Camargo -- */ --public class JmfMediaManager extends JingleMediaManager { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(JmfMediaManager.class); -- -- public static final String MEDIA_NAME = "JMF"; -- -- -- private List payloads = new ArrayList(); -- private String mediaLocator = null; -- -- /** -- * Creates a Media Manager instance -- */ -- public JmfMediaManager(JingleTransportManager transportManager) { -- super(transportManager); -- setupPayloads(); -- } -- -- /** -- * Creates a Media Manager instance -- * -- * @param mediaLocator Media Locator -- */ -- public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) { -- super(transportManager); -- this.mediaLocator = mediaLocator; -- setupPayloads(); -- } -- -- /** -- * Returns a new jingleMediaSession -- * -- * @param payloadType payloadType -- * @param remote remote Candidate -- * @param local local Candidate -- * @return JingleMediaSession -- */ -- public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) { -- return new AudioMediaSession(payloadType, remote, local, mediaLocator, jingleSession); -- } -- -- /** -- * Setup API supported Payloads -- */ -- private void setupPayloads() { -- payloads.add(new PayloadType.Audio(3, "gsm")); -- payloads.add(new PayloadType.Audio(4, "g723")); -- payloads.add(new PayloadType.Audio(0, "PCMU", 16000)); -- } -- -- /** -- * Return all supported Payloads for this Manager -- * -- * @return The Payload List -- */ -- public List getPayloads() { -- return payloads; -- } -- -- /** -- * Return the media locator or null if not defined -- * -- * @return media locator -- */ -- public String getMediaLocator() { -- return mediaLocator; -- } -- -- /** -- * Set the media locator -- * -- * @param mediaLocator media locator or null to use default -- */ -- public void setMediaLocator(String mediaLocator) { -- this.mediaLocator = mediaLocator; -- } -- -- /** -- * Runs JMFInit the first time the application is started so that capture -- * devices are properly detected and initialized by JMF. -- */ -- public static void setupJMF() { -- // .jmf is the place where we store the jmf.properties file used -- // by JMF. if the directory does not exist or it does not contain -- // a jmf.properties file. or if the jmf.properties file has 0 length -- // then this is the first time we're running and should continue to -- // with JMFInit -- String homeDir = System.getProperty("user.home"); -- File jmfDir = new File(homeDir, ".jmf"); -- String classpath = System.getProperty("java.class.path"); -- classpath += System.getProperty("path.separator") -- + jmfDir.getAbsolutePath(); -- System.setProperty("java.class.path", classpath); -- -- if (!jmfDir.exists()) -- jmfDir.mkdir(); -- -- File jmfProperties = new File(jmfDir, "jmf.properties"); -- -- if (!jmfProperties.exists()) { -- try { -- jmfProperties.createNewFile(); -- } -- catch (IOException ex) { -- LOGGER.debug("Failed to create jmf.properties"); -- ex.printStackTrace(); -- } -- } -- -- // if we're running on linux checkout that libjmutil.so is where it -- // should be and put it there. -- runLinuxPreInstall(); -- -- //if (jmfProperties.length() == 0) { -- new JMFInit(null, false); -- //} -- -- } -- -- private static void runLinuxPreInstall() { -- // @TODO Implement Linux Pre-Install -- } -- -- public String getName() { -- return MEDIA_NAME; -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java (working copy) -@@ -1,553 +0,0 @@ --/** -- * $RCSfile: AudioChannel.java,v $ -- * $Revision: 1.1 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --package org.jivesoftware.smackx.jingle.mediaimpl.jmf; -- --import java.io.IOException; --import java.net.InetAddress; --import java.net.UnknownHostException; --import java.util.ArrayList; --import java.util.List; -- --import javax.media.Codec; --import javax.media.Controller; --import javax.media.ControllerClosedEvent; --import javax.media.ControllerEvent; --import javax.media.ControllerListener; --import javax.media.Format; --import javax.media.MediaLocator; --import javax.media.NoProcessorException; --import javax.media.Processor; --import javax.media.UnsupportedPlugInException; --import javax.media.control.BufferControl; --import javax.media.control.PacketSizeControl; --import javax.media.control.TrackControl; --import javax.media.format.AudioFormat; --import javax.media.protocol.ContentDescriptor; --import javax.media.protocol.DataSource; --import javax.media.protocol.PushBufferDataSource; --import javax.media.protocol.PushBufferStream; --import javax.media.rtp.InvalidSessionAddressException; --import javax.media.rtp.RTPManager; --import javax.media.rtp.SendStream; --import javax.media.rtp.SessionAddress; -- --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; -- --/** -- * An Easy to use Audio Channel implemented using JMF. -- * It sends and receives jmf for and from desired IPs and ports. -- * Also has a rport Symetric behavior for better NAT Traversal. -- * It send data from a defined port and receive data in the same port, making NAT binds easier. -- *

-- * Send from portA to portB and receive from portB in portA. -- *

-- * Sending -- * portA ---> portB -- *

-- * Receiving -- * portB ---> portA -- *

-- * Transmit and Receive are interdependents. To receive you MUST trasmit. -- * -- * @author Thiago Camargo -- */ --public class AudioChannel { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioChannel.class); -- -- private MediaLocator locator; -- private String localIpAddress; -- private String remoteIpAddress; -- private int localPort; -- private int portBase; -- private Format format; -- -- private Processor processor = null; -- private RTPManager rtpMgrs[]; -- private DataSource dataOutput = null; -- private AudioReceiver audioReceiver; -- -- private List sendStreams = new ArrayList(); -- -- private JingleMediaSession jingleMediaSession; -- -- private boolean started = false; -- -- /** -- * Creates an Audio Channel for a desired jmf locator. For instance: new MediaLocator("dsound://") -- * -- * @param locator media locator -- * @param localIpAddress local IP address -- * @param remoteIpAddress remote IP address -- * @param localPort local port number -- * @param remotePort remote port number -- * @param format audio format -- */ -- public AudioChannel(MediaLocator locator, -- String localIpAddress, -- String remoteIpAddress, -- int localPort, -- int remotePort, -- Format format, JingleMediaSession jingleMediaSession) { -- -- this.locator = locator; -- this.localIpAddress = localIpAddress; -- this.remoteIpAddress = remoteIpAddress; -- this.localPort = localPort; -- this.portBase = remotePort; -- this.format = format; -- this.jingleMediaSession = jingleMediaSession; -- } -- -- /** -- * Starts the transmission. Returns null if transmission started ok. -- * Otherwise it returns a string with the reason why the setup failed. -- * Starts receive also. -- * -- * @return result description -- */ -- public synchronized String start() { -- if (started) return null; -- -- // Create a processor for the specified jmf locator -- String result = createProcessor(); -- if (result != null) { -- started = false; -- } -- -- // Create an RTP session to transmit the output of the -- // processor to the specified IP address and port no. -- result = createTransmitter(); -- if (result != null) { -- processor.close(); -- processor = null; -- started = false; -- } -- else { -- started = true; -- } -- -- // Start the transmission -- processor.start(); -- -- return null; -- } -- -- /** -- * Stops the transmission if already started. -- * Stops the receiver also. -- */ -- public void stop() { -- if (!started) return; -- synchronized (this) { -- try { -- started = false; -- if (processor != null) { -- processor.stop(); -- processor = null; -- -- for (RTPManager rtpMgr : rtpMgrs) { -- rtpMgr.removeReceiveStreamListener(audioReceiver); -- rtpMgr.removeSessionListener(audioReceiver); -- rtpMgr.removeTargets("Session ended."); -- rtpMgr.dispose(); -- } -- -- sendStreams.clear(); -- -- } -- } -- catch (Exception e) { -- e.printStackTrace(); -- } -- } -- } -- -- private String createProcessor() { -- if (locator == null) -- return "Locator is null"; -- -- DataSource ds; -- -- try { -- ds = javax.media.Manager.createDataSource(locator); -- } -- catch (Exception e) { -- // Try JavaSound Locator as a last resort -- try { -- ds = javax.media.Manager.createDataSource(new MediaLocator("javasound://")); -- } -- catch (Exception ee) { -- return "Couldn't create DataSource"; -- } -- } -- -- // Try to create a processor to handle the input jmf locator -- try { -- processor = javax.media.Manager.createProcessor(ds); -- } -- catch (NoProcessorException npe) { -- npe.printStackTrace(); -- return "Couldn't create processor"; -- } -- catch (IOException ioe) { -- ioe.printStackTrace(); -- return "IOException creating processor"; -- } -- -- // Wait for it to configure -- boolean result = waitForState(processor, Processor.Configured); -- if (!result){ -- return "Couldn't configure processor"; -- } -- -- // Get the tracks from the processor -- TrackControl[] tracks = processor.getTrackControls(); -- -- // Do we have atleast one track? -- if (tracks == null || tracks.length < 1){ -- return "Couldn't find tracks in processor"; -- } -- -- // Set the output content descriptor to RAW_RTP -- // This will limit the supported formats reported from -- // Track.getSupportedFormats to only valid RTP formats. -- ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP); -- processor.setContentDescriptor(cd); -- -- Format supported[]; -- Format chosen = null; -- boolean atLeastOneTrack = false; -- -- // Program the tracks. -- for (int i = 0; i < tracks.length; i++) { -- if (tracks[i].isEnabled()) { -- -- supported = tracks[i].getSupportedFormats(); -- -- if (supported.length > 0) { -- for (Format format : supported) { -- if (format instanceof AudioFormat) { -- if (this.format.matches(format)) -- chosen = format; -- } -- } -- if (chosen != null) { -- tracks[i].setFormat(chosen); -- LOGGER.error("Track " + i + " is set to transmit as:"); -- LOGGER.error(" " + chosen); -- -- if (tracks[i].getFormat() instanceof AudioFormat) { -- int packetRate = 20; -- PacketSizeControl pktCtrl = (PacketSizeControl) processor.getControl(PacketSizeControl.class.getName()); -- if (pktCtrl != null) { -- try { -- pktCtrl.setPacketSize(getPacketSize(tracks[i].getFormat(), packetRate)); -- } -- catch (IllegalArgumentException e) { -- pktCtrl.setPacketSize(80); -- // Do nothing -- } -- } -- -- if (tracks[i].getFormat().getEncoding().equals(AudioFormat.ULAW_RTP)) { -- Codec codec[] = new Codec[3]; -- -- codec[0] = new com.ibm.media.codec.audio.rc.RCModule(); -- codec[1] = new com.ibm.media.codec.audio.ulaw.JavaEncoder(); -- codec[2] = new com.sun.media.codec.audio.ulaw.Packetizer(); -- ((com.sun.media.codec.audio.ulaw.Packetizer) codec -- [2]).setPacketSize(160); -- -- try { -- tracks[i].setCodecChain(codec); -- } -- catch (UnsupportedPlugInException e) { -- e.printStackTrace(); -- } -- } -- -- } -- -- atLeastOneTrack = true; -- } -- else -- tracks[i].setEnabled(false); -- } -- else -- tracks[i].setEnabled(false); -- } -- } -- -- if (!atLeastOneTrack) -- return "Couldn't set any of the tracks to a valid RTP format"; -- -- result = waitForState(processor, Controller.Realized); -- if (!result) -- return "Couldn't realize processor"; -- -- // Get the output data source of the processor -- dataOutput = processor.getDataOutput(); -- -- return null; -- } -- -- /** -- * Get the best packet size for a given codec and a codec rate -- * -- * @param codecFormat -- * @param milliseconds -- * @return -- * @throws IllegalArgumentException -- */ -- private int getPacketSize(Format codecFormat, int milliseconds) throws IllegalArgumentException { -- String encoding = codecFormat.getEncoding(); -- if (encoding.equalsIgnoreCase(AudioFormat.GSM) || -- encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) { -- return milliseconds * 4; // 1 byte per millisec -- } -- else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) || -- encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) { -- return milliseconds * 8; -- } -- else { -- throw new IllegalArgumentException("Unknown codec type"); -- } -- } -- -- /** -- * Use the RTPManager API to create sessions for each jmf -- * track of the processor. -- * -- * @return description -- */ -- private String createTransmitter() { -- -- // Cheated. Should have checked the type. -- PushBufferDataSource pbds = (PushBufferDataSource) dataOutput; -- PushBufferStream pbss[] = pbds.getStreams(); -- -- rtpMgrs = new RTPManager[pbss.length]; -- SessionAddress localAddr, destAddr; -- InetAddress ipAddr; -- SendStream sendStream; -- audioReceiver = new AudioReceiver(this, jingleMediaSession); -- int port; -- -- for (int i = 0; i < pbss.length; i++) { -- try { -- rtpMgrs[i] = RTPManager.newInstance(); -- -- port = portBase + 2 * i; -- ipAddr = InetAddress.getByName(remoteIpAddress); -- -- localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress), -- localPort); -- -- destAddr = new SessionAddress(ipAddr, port); -- -- rtpMgrs[i].addReceiveStreamListener(audioReceiver); -- rtpMgrs[i].addSessionListener(audioReceiver); -- -- BufferControl bc = (BufferControl) rtpMgrs[i].getControl("javax.media.control.BufferControl"); -- if (bc != null) { -- int bl = 160; -- bc.setBufferLength(bl); -- } -- -- try { -- -- rtpMgrs[i].initialize(localAddr); -- -- } -- catch (InvalidSessionAddressException e) { -- // In case the local address is not allowed to read, we user another local address -- SessionAddress sessAddr = new SessionAddress(); -- localAddr = new SessionAddress(sessAddr.getDataAddress(), -- localPort); -- rtpMgrs[i].initialize(localAddr); -- } -- -- rtpMgrs[i].addTarget(destAddr); -- -- LOGGER.error("Created RTP session at " + localPort + " to: " + remoteIpAddress + " " + port); -- -- sendStream = rtpMgrs[i].createSendStream(dataOutput, i); -- -- sendStreams.add(sendStream); -- -- sendStream.start(); -- -- } -- catch (Exception e) { -- e.printStackTrace(); -- return e.getMessage(); -- } -- } -- -- return null; -- } -- -- /** -- * Set transmit activity. If the active is true, the instance should trasmit. -- * If it is set to false, the instance should pause transmit. -- * -- * @param active active state -- */ -- public void setTrasmit(boolean active) { -- for (SendStream sendStream : sendStreams) { -- try { -- if (active) { -- sendStream.start(); -- LOGGER.debug("START"); -- } -- else { -- sendStream.stop(); -- LOGGER.debug("STOP"); -- } -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- -- } -- } -- -- /** -- * ************************************************************* -- * Convenience methods to handle processor's state changes. -- * ************************************************************** -- */ -- -- private Integer stateLock = 0; -- private boolean failed = false; -- -- Integer getStateLock() { -- return stateLock; -- } -- -- void setFailed() { -- failed = true; -- } -- -- private synchronized boolean waitForState(Processor p, int state) { -- p.addControllerListener(new StateListener()); -- failed = false; -- -- // Call the required method on the processor -- if (state == Processor.Configured) { -- p.configure(); -- } -- else if (state == Processor.Realized) { -- p.realize(); -- } -- -- // Wait until we get an event that confirms the -- // success of the method, or a failure event. -- // See StateListener inner class -- while (p.getState() < state && !failed) { -- synchronized (getStateLock()) { -- try { -- getStateLock().wait(); -- } -- catch (InterruptedException ie) { -- return false; -- } -- } -- } -- -- return !failed; -- } -- -- /** -- * ************************************************************* -- * Inner Classes -- * ************************************************************** -- */ -- -- class StateListener implements ControllerListener { -- -- public void controllerUpdate(ControllerEvent ce) { -- -- // If there was an error during configure or -- // realize, the processor will be closed -- if (ce instanceof ControllerClosedEvent) -- setFailed(); -- -- // All controller events, send a notification -- // to the waiting thread in waitForState method. -- if (ce != null) { -- synchronized (getStateLock()) { -- getStateLock().notifyAll(); -- } -- } -- } -- } -- -- public static void main(String args[]) { -- -- InetAddress localhost; -- try { -- localhost = InetAddress.getLocalHost(); -- -- AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP), null); -- AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP), null); -- -- audioChannel0.start(); -- audioChannel1.start(); -- -- try { -- Thread.sleep(5000); -- } -- catch (InterruptedException e) { -- e.printStackTrace(); -- } -- -- audioChannel0.setTrasmit(false); -- audioChannel1.setTrasmit(false); -- -- try { -- Thread.sleep(5000); -- } -- catch (InterruptedException e) { -- e.printStackTrace(); -- } -- -- audioChannel0.setTrasmit(true); -- audioChannel1.setTrasmit(true); -- -- try { -- Thread.sleep(5000); -- } -- catch (InterruptedException e) { -- e.printStackTrace(); -- } -- -- audioChannel0.stop(); -- audioChannel1.stop(); -- -- } -- catch (UnknownHostException e) { -- e.printStackTrace(); -- } -- -- } --} -\ No newline at end of file -Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java (working copy) -@@ -1,55 +0,0 @@ --/** -- * $RCSfile: AudioFormatUtils.java,v $ -- * $Revision: 1.1 $ -- * $Date: 08/11/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --package org.jivesoftware.smackx.jingle.mediaimpl.jmf; -- --import org.jivesoftware.smackx.jingle.media.PayloadType; -- --import javax.media.format.AudioFormat; -- --/** -- * Audio Format Utils. -- * -- * @author Thiago Camargo -- */ --public class AudioFormatUtils { -- -- /** -- * Return a JMF AudioFormat for a given Jingle Payload type. -- * Return null if the payload is not supported by this jmf API. -- * -- * @param payloadtype payloadtype -- * @return correspondent audioType -- */ -- public static AudioFormat getAudioFormat(PayloadType payloadtype) { -- -- switch (payloadtype.getId()) { -- case 0: -- return new AudioFormat(AudioFormat.ULAW_RTP); -- case 3: -- return new AudioFormat(AudioFormat.GSM_RTP); -- case 4: -- return new AudioFormat(AudioFormat.G723_RTP); -- default: -- return null; -- } -- -- } -- --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java (working copy) -@@ -1,134 +0,0 @@ --/** -- * $RCSfile: SpeexMediaManager.java,v $ -- * $Revision: 1.3 $ -- * $Date: 25/12/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --package org.jivesoftware.smackx.jingle.mediaimpl.jspeex; -- --import java.io.File; --import java.io.IOException; --import java.util.ArrayList; --import java.util.List; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaManager; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.mediaimpl.JMFInit; --import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --/** -- * Implements a jingleMediaManager using JMF based API and JSpeex. -- * It supports Speex codec. -- * This API only currently works on windows. -- * -- * @author Thiago Camargo -- */ --public class SpeexMediaManager extends JingleMediaManager { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(SpeexMediaManager.class); -- -- public static final String MEDIA_NAME = "Speex"; -- -- private List payloads = new ArrayList(); -- -- public SpeexMediaManager(JingleTransportManager transportManager) { -- super(transportManager); -- setupPayloads(); -- setupJMF(); -- } -- -- /** -- * Returns a new jingleMediaSession -- * -- * @param payloadType payloadType -- * @param remote remote Candidate -- * @param local local Candidate -- * @return JingleMediaSession -- */ -- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) { -- return new AudioMediaSession(payloadType, remote, local, null,null); -- } -- -- /** -- * Setup API supported Payloads -- */ -- private void setupPayloads() { -- payloads.add(new PayloadType.Audio(15, "speex")); -- } -- -- /** -- * Return all supported Payloads for this Manager -- * -- * @return The Payload List -- */ -- public List getPayloads() { -- return payloads; -- } -- -- /** -- * Runs JMFInit the first time the application is started so that capture -- * devices are properly detected and initialized by JMF. -- */ -- public static void setupJMF() { -- // .jmf is the place where we store the jmf.properties file used -- // by JMF. if the directory does not exist or it does not contain -- // a jmf.properties file. or if the jmf.properties file has 0 length -- // then this is the first time we're running and should continue to -- // with JMFInit -- String homeDir = System.getProperty("user.home"); -- File jmfDir = new File(homeDir, ".jmf"); -- String classpath = System.getProperty("java.class.path"); -- classpath += System.getProperty("path.separator") -- + jmfDir.getAbsolutePath(); -- System.setProperty("java.class.path", classpath); -- -- if (!jmfDir.exists()) -- jmfDir.mkdir(); -- -- File jmfProperties = new File(jmfDir, "jmf.properties"); -- -- if (!jmfProperties.exists()) { -- try { -- jmfProperties.createNewFile(); -- } -- catch (IOException ex) { -- LOGGER.debug("Failed to create jmf.properties"); -- ex.printStackTrace(); -- } -- } -- -- // if we're running on linux checkout that libjmutil.so is where it -- // should be and put it there. -- runLinuxPreInstall(); -- -- if (jmfProperties.length() == 0) { -- new JMFInit(null, false); -- } -- -- } -- -- private static void runLinuxPreInstall() { -- // @TODO Implement Linux Pre-Install -- } -- -- public String getName() { -- return MEDIA_NAME; -- } --} -Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java -=================================================================== ---- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java (revision 11644) -+++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java (working copy) -@@ -1,245 +0,0 @@ --/** -- * $RCSfile: AudioMediaSession.java,v $ -- * $Revision: 1.1 $ -- * $Date: 25/12/2006 -- *

-- * Copyright 2003-2006 Jive Software. -- *

-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- *

-- * http://www.apache.org/licenses/LICENSE-2.0 -- *

-- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jivesoftware.smackx.jingle.mediaimpl.jspeex; -- --import java.io.IOException; --import java.net.DatagramSocket; --import java.net.InetAddress; --import java.net.ServerSocket; --import java.security.GeneralSecurityException; -- --import javax.media.NoProcessorException; --import javax.media.format.UnsupportedFormatException; --import javax.media.rtp.rtcp.SenderReport; --import javax.media.rtp.rtcp.SourceDescription; -- --import mil.jfcom.cie.media.session.MediaSession; --import mil.jfcom.cie.media.session.MediaSessionListener; --import mil.jfcom.cie.media.session.StreamPlayer; --import mil.jfcom.cie.media.srtp.packetizer.SpeexFormat; -- --import org.jivesoftware.smackx.jingle.JingleSession; --import org.jivesoftware.smackx.jingle.SmackLogger; --import org.jivesoftware.smackx.jingle.media.JingleMediaSession; --import org.jivesoftware.smackx.jingle.media.PayloadType; --import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -- --/** -- * This Class implements a complete JingleMediaSession. -- * It sould be used to transmit and receive audio captured from the Mic. -- * This Class should be automaticly controlled by JingleSession. -- * But you could also use in any VOIP application. -- * For better NAT Traversal support this implementation don't support only receive or only transmit. -- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit() -- * -- * @author Thiago Camargo -- */ -- --public class AudioMediaSession extends JingleMediaSession implements MediaSessionListener { -- -- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class); -- -- private MediaSession mediaSession; -- -- /** -- * Create a Session using Speex Codec -- * -- * @param localhost localHost -- * @param localPort localPort -- * @param remoteHost remoteHost -- * @param remotePort remotePort -- * @param eventHandler eventHandler -- * @param quality quality -- * @param secure secure -- * @param micOn micOn -- * @return MediaSession -- * @throws NoProcessorException -- * @throws UnsupportedFormatException -- * @throws IOException -- * @throws GeneralSecurityException -- */ -- public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException { -- -- SpeexFormat.setFramesPerPacket(1); -- /** -- * The master key. Hardcoded for now. -- */ -- byte[] masterKey = new byte[]{(byte) 0xE1, (byte) 0xF9, 0x7A, 0x0D, 0x3E, 0x01, (byte) 0x8B, (byte) 0xE0, (byte) 0xD6, 0x4F, (byte) 0xA3, 0x2C, 0x06, (byte) 0xDE, 0x41, 0x39}; -- -- /** -- * The master salt. Hardcoded for now. -- */ -- byte[] masterSalt = new byte[]{0x0E, (byte) 0xC6, 0x75, (byte) 0xAD, 0x49, (byte) 0x8A, (byte) 0xFE, (byte) 0xEB, (byte) 0xB6, (byte) 0x96, 0x0B, 0x3A, (byte) 0xAB, (byte) 0xE6}; -- -- DatagramSocket[] localPorts = MediaSession.getLocalPorts(InetAddress.getByName(localhost), localPort); -- MediaSession session = MediaSession.createInstance(remoteHost, remotePort, localPorts, quality, secure, masterKey, masterSalt); -- session.setListener(eventHandler); -- -- session.setSourceDescription(new SourceDescription[]{new SourceDescription(SourceDescription.SOURCE_DESC_NAME, "Superman", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_EMAIL, "cdcie.tester@je.jfcom.mil", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_LOC, InetAddress.getByName(localhost) + " Port " + session.getLocalDataPort(), 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_TOOL, "JFCOM CDCIE Audio Chat", 1, false)}); -- return session; -- } -- -- -- /** -- * Creates a org.jivesoftware.jingleaudio.jspeex.AudioMediaSession with defined payload type, remote and local candidates -- * -- * @param payloadType Payload of the jmf -- * @param remote the remote information. The candidate that the jmf will be sent to. -- * @param local the local information. The candidate that will receive the jmf -- * @param locator media locator -- */ -- public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, -- final TransportCandidate local, String locator, JingleSession jingleSession) { -- super(payloadType, remote, local, locator == null ? "dsound://" : locator, jingleSession); -- initialize(); -- } -- -- /** -- * Initialize the Audio Channel to make it able to send and receive audio -- */ -- public void initialize() { -- -- String ip; -- String localIp; -- int localPort; -- int remotePort; -- -- if (this.getLocal().getSymmetric() != null) { -- ip = this.getLocal().getIp(); -- localIp = this.getLocal().getLocalIp(); -- localPort = getFreePort(); -- remotePort = this.getLocal().getSymmetric().getPort(); -- -- LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort); -- -- } -- else { -- ip = this.getRemote().getIp(); -- localIp = this.getLocal().getLocalIp(); -- localPort = this.getLocal().getPort(); -- remotePort = this.getRemote().getPort(); -- } -- -- try { -- mediaSession = createSession(localIp, localPort, ip, remotePort, this, 2, false, true); -- } -- catch (NoProcessorException e) { -- e.printStackTrace(); -- } -- catch (UnsupportedFormatException e) { -- e.printStackTrace(); -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- catch (GeneralSecurityException e) { -- e.printStackTrace(); -- } -- } -- -- /** -- * Starts transmission and for NAT Traversal reasons start receiving also. -- */ -- public void startTrasmit() { -- try { -- LOGGER.debug("start"); -- mediaSession.start(true); -- this.mediaReceived(""); -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- } -- -- /** -- * Set transmit activity. If the active is true, the instance should trasmit. -- * If it is set to false, the instance should pause transmit. -- * -- * @param active active state -- */ -- public void setTrasmit(boolean active) { -- // Do nothing -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void startReceive() { -- // Do nothing -- } -- -- /** -- * Stops transmission and for NAT Traversal reasons stop receiving also. -- */ -- public void stopTrasmit() { -- if (mediaSession != null) -- mediaSession.close(); -- } -- -- /** -- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf -- */ -- public void stopReceive() { -- // Do nothing -- } -- -- public void newStreamIdentified(StreamPlayer streamPlayer) { -- } -- -- public void senderReportReceived(SenderReport report) { -- } -- -- public void streamClosed(StreamPlayer stream, boolean timeout) { -- } -- -- /** -- * Obtain a free port we can use. -- * -- * @return A free port number. -- */ -- protected int getFreePort() { -- ServerSocket ss; -- int freePort = 0; -- -- for (int i = 0; i < 10; i++) { -- freePort = (int) (10000 + Math.round(Math.random() * 10000)); -- freePort = freePort % 2 == 0 ? freePort : freePort + 1; -- try { -- ss = new ServerSocket(freePort); -- freePort = ss.getLocalPort(); -- ss.close(); -- return freePort; -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- } -- try { -- ss = new ServerSocket(0); -- freePort = ss.getLocalPort(); -- ss.close(); -- } -- catch (IOException e) { -- e.printStackTrace(); -- } -- return freePort; -- } --} diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/COPYING --- a/doc/asmack-beem/beem_patches/COPYING Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/beem_patches/README.txt --- a/doc/asmack-beem/beem_patches/README.txt Tue Jan 18 00:26:02 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -This directory contains different patch to apply on asmack sources. These -patches will allow us to build a custom flavour of asmack for Beem. This -directory must be copied in the patch directory of asmack in order to be used. -Then build asmack the usual way. - -All the patches are released under the Apache License, Version 2.0 -You may obtain a copy of the License at -http://www.apache.org.licenses/LICENCE-2.0 - diff -r 6c2c4bfa43d0 -r d7ddcccdff8a doc/asmack-beem/lib/jstun.jar Binary file doc/asmack-beem/lib/jstun.jar has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a libs/asmack-android-10-beem.jar Binary file libs/asmack-android-10-beem.jar has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a libs/asmack-android-7-beem.jar Binary file libs/asmack-android-7-beem.jar has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a libs/lcrypto-jdk16-146-20110415.jar Binary file libs/lcrypto-jdk16-146-20110415.jar has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a project.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project.properties Tue Jun 05 16:29:25 2012 +0200 @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-10 diff -r 6c2c4bfa43d0 -r d7ddcccdff8a res/drawable/background.png Binary file res/drawable/background.png has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a res/drawable/logo_encryption.png Binary file res/drawable/logo_encryption.png has changed diff -r 6c2c4bfa43d0 -r d7ddcccdff8a res/layout/addcontact.xml --- a/res/layout/addcontact.xml Tue Jan 18 00:26:02 2011 +0100 +++ b/res/layout/addcontact.xml Tue Jun 05 16:29:25 2012 +0200 @@ -32,8 +32,7 @@