diff options
Diffstat (limited to 'talk/app/webrtc/java/src/org/webrtc/PeerConnection.java')
-rw-r--r-- | talk/app/webrtc/java/src/org/webrtc/PeerConnection.java | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java new file mode 100644 index 0000000000..50023001d7 --- /dev/null +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java @@ -0,0 +1,294 @@ +/* + * libjingle + * Copyright 2013 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +package org.webrtc; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Java-land version of the PeerConnection APIs; wraps the C++ API + * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the + * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and + * http://www.w3.org/TR/mediacapture-streams/ + */ +public class PeerConnection { + static { + System.loadLibrary("jingle_peerconnection_so"); + } + + /** Tracks PeerConnectionInterface::IceGatheringState */ + public enum IceGatheringState { NEW, GATHERING, COMPLETE }; + + + /** Tracks PeerConnectionInterface::IceConnectionState */ + public enum IceConnectionState { + NEW, CHECKING, CONNECTED, COMPLETED, FAILED, DISCONNECTED, CLOSED + }; + + /** Tracks PeerConnectionInterface::SignalingState */ + public enum SignalingState { + STABLE, HAVE_LOCAL_OFFER, HAVE_LOCAL_PRANSWER, HAVE_REMOTE_OFFER, + HAVE_REMOTE_PRANSWER, CLOSED + }; + + /** Java version of PeerConnectionObserver. */ + public static interface Observer { + /** Triggered when the SignalingState changes. */ + public void onSignalingChange(SignalingState newState); + + /** Triggered when the IceConnectionState changes. */ + public void onIceConnectionChange(IceConnectionState newState); + + /** Triggered when the ICE connection receiving status changes. */ + public void onIceConnectionReceivingChange(boolean receiving); + + /** Triggered when the IceGatheringState changes. */ + public void onIceGatheringChange(IceGatheringState newState); + + /** Triggered when a new ICE candidate has been found. */ + public void onIceCandidate(IceCandidate candidate); + + /** Triggered when media is received on a new stream from remote peer. */ + public void onAddStream(MediaStream stream); + + /** Triggered when a remote peer close a stream. */ + public void onRemoveStream(MediaStream stream); + + /** Triggered when a remote peer opens a DataChannel. */ + public void onDataChannel(DataChannel dataChannel); + + /** Triggered when renegotiation is necessary. */ + public void onRenegotiationNeeded(); + } + + /** Java version of PeerConnectionInterface.IceServer. */ + public static class IceServer { + public final String uri; + public final String username; + public final String password; + + /** Convenience constructor for STUN servers. */ + public IceServer(String uri) { + this(uri, "", ""); + } + + public IceServer(String uri, String username, String password) { + this.uri = uri; + this.username = username; + this.password = password; + } + + public String toString() { + return uri + "[" + username + ":" + password + "]"; + } + } + + /** Java version of PeerConnectionInterface.IceTransportsType */ + public enum IceTransportsType { + NONE, RELAY, NOHOST, ALL + }; + + /** Java version of PeerConnectionInterface.BundlePolicy */ + public enum BundlePolicy { + BALANCED, MAXBUNDLE, MAXCOMPAT + }; + + /** Java version of PeerConnectionInterface.RtcpMuxPolicy */ + public enum RtcpMuxPolicy { + NEGOTIATE, REQUIRE + }; + + /** Java version of PeerConnectionInterface.TcpCandidatePolicy */ + public enum TcpCandidatePolicy { + ENABLED, DISABLED + }; + + /** Java version of rtc::KeyType */ + public enum KeyType { + RSA, ECDSA + } + + /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */ + public enum ContinualGatheringPolicy { + GATHER_ONCE, GATHER_CONTINUALLY + } + + /** Java version of PeerConnectionInterface.RTCConfiguration */ + public static class RTCConfiguration { + public IceTransportsType iceTransportsType; + public List<IceServer> iceServers; + public BundlePolicy bundlePolicy; + public RtcpMuxPolicy rtcpMuxPolicy; + public TcpCandidatePolicy tcpCandidatePolicy; + public int audioJitterBufferMaxPackets; + public boolean audioJitterBufferFastAccelerate; + public int iceConnectionReceivingTimeout; + public KeyType keyType; + public ContinualGatheringPolicy continualGatheringPolicy; + + public RTCConfiguration(List<IceServer> iceServers) { + iceTransportsType = IceTransportsType.ALL; + bundlePolicy = BundlePolicy.BALANCED; + rtcpMuxPolicy = RtcpMuxPolicy.NEGOTIATE; + tcpCandidatePolicy = TcpCandidatePolicy.ENABLED; + this.iceServers = iceServers; + audioJitterBufferMaxPackets = 50; + audioJitterBufferFastAccelerate = false; + iceConnectionReceivingTimeout = -1; + keyType = KeyType.ECDSA; + continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE; + } + }; + + private final List<MediaStream> localStreams; + private final long nativePeerConnection; + private final long nativeObserver; + private List<RtpSender> senders; + private List<RtpReceiver> receivers; + + PeerConnection(long nativePeerConnection, long nativeObserver) { + this.nativePeerConnection = nativePeerConnection; + this.nativeObserver = nativeObserver; + localStreams = new LinkedList<MediaStream>(); + senders = new LinkedList<RtpSender>(); + receivers = new LinkedList<RtpReceiver>(); + } + + // JsepInterface. + public native SessionDescription getLocalDescription(); + + public native SessionDescription getRemoteDescription(); + + public native DataChannel createDataChannel( + String label, DataChannel.Init init); + + public native void createOffer( + SdpObserver observer, MediaConstraints constraints); + + public native void createAnswer( + SdpObserver observer, MediaConstraints constraints); + + public native void setLocalDescription( + SdpObserver observer, SessionDescription sdp); + + public native void setRemoteDescription( + SdpObserver observer, SessionDescription sdp); + + public native boolean setConfiguration(RTCConfiguration config); + + public boolean addIceCandidate(IceCandidate candidate) { + return nativeAddIceCandidate( + candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); + } + + public boolean addStream(MediaStream stream) { + boolean ret = nativeAddLocalStream(stream.nativeStream); + if (!ret) { + return false; + } + localStreams.add(stream); + return true; + } + + public void removeStream(MediaStream stream) { + nativeRemoveLocalStream(stream.nativeStream); + localStreams.remove(stream); + } + + // Note that calling getSenders will dispose of the senders previously + // returned (and same goes for getReceivers). + public List<RtpSender> getSenders() { + for (RtpSender sender : senders) { + sender.dispose(); + } + senders = nativeGetSenders(); + return Collections.unmodifiableList(senders); + } + + public List<RtpReceiver> getReceivers() { + for (RtpReceiver receiver : receivers) { + receiver.dispose(); + } + receivers = nativeGetReceivers(); + return Collections.unmodifiableList(receivers); + } + + public boolean getStats(StatsObserver observer, MediaStreamTrack track) { + return nativeGetStats(observer, (track == null) ? 0 : track.nativeTrack); + } + + // TODO(fischman): add support for DTMF-related methods once that API + // stabilizes. + public native SignalingState signalingState(); + + public native IceConnectionState iceConnectionState(); + + public native IceGatheringState iceGatheringState(); + + public native void close(); + + public void dispose() { + close(); + for (MediaStream stream : localStreams) { + nativeRemoveLocalStream(stream.nativeStream); + stream.dispose(); + } + localStreams.clear(); + for (RtpSender sender : senders) { + sender.dispose(); + } + senders.clear(); + for (RtpReceiver receiver : receivers) { + receiver.dispose(); + } + receivers.clear(); + freePeerConnection(nativePeerConnection); + freeObserver(nativeObserver); + } + + private static native void freePeerConnection(long nativePeerConnection); + + private static native void freeObserver(long nativeObserver); + + private native boolean nativeAddIceCandidate( + String sdpMid, int sdpMLineIndex, String iceCandidateSdp); + + private native boolean nativeAddLocalStream(long nativeStream); + + private native void nativeRemoveLocalStream(long nativeStream); + + private native boolean nativeGetStats( + StatsObserver observer, long nativeTrack); + + private native List<RtpSender> nativeGetSenders(); + + private native List<RtpReceiver> nativeGetReceivers(); +} |