1 /* 2 * libjingle 3 * Copyright 2013, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 29 package org.webrtc; 30 31 import java.util.LinkedList; 32 import java.util.List; 33 34 /** 35 * Java-land version of the PeerConnection APIs; wraps the C++ API 36 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the 37 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and 38 * http://www.w3.org/TR/mediacapture-streams/ 39 */ 40 public class PeerConnection { 41 static { 42 System.loadLibrary("jingle_peerconnection_so"); 43 } 44 45 /** Tracks PeerConnectionInterface::IceGatheringState */ 46 public enum IceGatheringState { NEW, GATHERING, COMPLETE }; 47 48 49 /** Tracks PeerConnectionInterface::IceConnectionState */ 50 public enum IceConnectionState { 51 NEW, CHECKING, CONNECTED, COMPLETED, FAILED, DISCONNECTED, CLOSED 52 }; 53 54 /** Tracks PeerConnectionInterface::SignalingState */ 55 public enum SignalingState { 56 STABLE, HAVE_LOCAL_OFFER, HAVE_LOCAL_PRANSWER, HAVE_REMOTE_OFFER, 57 HAVE_REMOTE_PRANSWER, CLOSED 58 }; 59 60 /** Java version of PeerConnectionObserver. */ 61 public static interface Observer { 62 /** Triggered when the SignalingState changes. */ 63 public void onSignalingChange(SignalingState newState); 64 65 /** Triggered when the IceConnectionState changes. */ 66 public void onIceConnectionChange(IceConnectionState newState); 67 68 /** Triggered when the IceGatheringState changes. */ 69 public void onIceGatheringChange(IceGatheringState newState); 70 71 /** Triggered when a new ICE candidate has been found. */ 72 public void onIceCandidate(IceCandidate candidate); 73 74 /** Triggered on any error. */ 75 public void onError(); 76 77 /** Triggered when media is received on a new stream from remote peer. */ 78 public void onAddStream(MediaStream stream); 79 80 /** Triggered when a remote peer close a stream. */ 81 public void onRemoveStream(MediaStream stream); 82 83 /** Triggered when a remote peer opens a DataChannel. */ 84 public void onDataChannel(DataChannel dataChannel); 85 } 86 87 /** Java version of PeerConnectionInterface.IceServer. */ 88 public static class IceServer { 89 public final String uri; 90 public final String username; 91 public final String password; 92 93 /** Convenience constructor for STUN servers. */ 94 public IceServer(String uri) { 95 this(uri, "", ""); 96 } 97 98 public IceServer(String uri, String username, String password) { 99 this.uri = uri; 100 this.username = username; 101 this.password = password; 102 } 103 104 public String toString() { 105 return uri + "[" + username + ":" + password + "]"; 106 } 107 } 108 109 private final List<MediaStream> localStreams; 110 private final long nativePeerConnection; 111 private final long nativeObserver; 112 113 PeerConnection(long nativePeerConnection, long nativeObserver) { 114 this.nativePeerConnection = nativePeerConnection; 115 this.nativeObserver = nativeObserver; 116 localStreams = new LinkedList<MediaStream>(); 117 } 118 119 // JsepInterface. 120 public native SessionDescription getLocalDescription(); 121 122 public native SessionDescription getRemoteDescription(); 123 124 public native DataChannel createDataChannel( 125 String label, DataChannel.Init init); 126 127 public native void createOffer( 128 SdpObserver observer, MediaConstraints constraints); 129 130 public native void createAnswer( 131 SdpObserver observer, MediaConstraints constraints); 132 133 public native void setLocalDescription( 134 SdpObserver observer, SessionDescription sdp); 135 136 public native void setRemoteDescription( 137 SdpObserver observer, SessionDescription sdp); 138 139 public native boolean updateIce( 140 List<IceServer> iceServers, MediaConstraints constraints); 141 142 public boolean addIceCandidate(IceCandidate candidate) { 143 return nativeAddIceCandidate( 144 candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); 145 } 146 147 public boolean addStream( 148 MediaStream stream, MediaConstraints constraints) { 149 boolean ret = nativeAddLocalStream(stream.nativeStream, constraints); 150 if (!ret) { 151 return false; 152 } 153 localStreams.add(stream); 154 return true; 155 } 156 157 public void removeStream(MediaStream stream) { 158 nativeRemoveLocalStream(stream.nativeStream); 159 localStreams.remove(stream); 160 } 161 162 public boolean getStats(StatsObserver observer, MediaStreamTrack track) { 163 return nativeGetStats(observer, (track == null) ? 0 : track.nativeTrack); 164 } 165 166 // TODO(fischman): add support for DTMF-related methods once that API 167 // stabilizes. 168 public native SignalingState signalingState(); 169 170 public native IceConnectionState iceConnectionState(); 171 172 public native IceGatheringState iceGatheringState(); 173 174 public native void close(); 175 176 public void dispose() { 177 close(); 178 for (MediaStream stream : localStreams) { 179 stream.dispose(); 180 } 181 localStreams.clear(); 182 freePeerConnection(nativePeerConnection); 183 freeObserver(nativeObserver); 184 } 185 186 private static native void freePeerConnection(long nativePeerConnection); 187 188 private static native void freeObserver(long nativeObserver); 189 190 private native boolean nativeAddIceCandidate( 191 String sdpMid, int sdpMLineIndex, String iceCandidateSdp); 192 193 private native boolean nativeAddLocalStream( 194 long nativeStream, MediaConstraints constraints); 195 196 private native void nativeRemoveLocalStream(long nativeStream); 197 198 private native boolean nativeGetStats( 199 StatsObserver observer, long nativeTrack); 200 } 201