2013-07-10 00:45:36 +00:00
|
|
|
/*
|
2016-02-10 07:54:43 -08:00
|
|
|
* Copyright 2013 The WebRTC project authors. All Rights Reserved.
|
2013-07-10 00:45:36 +00:00
|
|
|
*
|
2016-02-10 07:54:43 -08:00
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
2013-07-10 00:45:36 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package org.webrtc;
|
|
|
|
|
|
2015-10-06 12:29:25 -07:00
|
|
|
import java.util.Collections;
|
2013-07-10 00:45:36 +00:00
|
|
|
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);
|
|
|
|
|
|
2015-07-08 11:08:35 -07:00
|
|
|
/** Triggered when the ICE connection receiving status changes. */
|
|
|
|
|
public void onIceConnectionReceivingChange(boolean receiving);
|
|
|
|
|
|
2013-07-10 00:45:36 +00:00
|
|
|
/** Triggered when the IceGatheringState changes. */
|
|
|
|
|
public void onIceGatheringChange(IceGatheringState newState);
|
|
|
|
|
|
|
|
|
|
/** Triggered when a new ICE candidate has been found. */
|
|
|
|
|
public void onIceCandidate(IceCandidate candidate);
|
|
|
|
|
|
2016-03-14 11:59:18 -07:00
|
|
|
/** Triggered when some ICE candidates have been removed. */
|
|
|
|
|
public void onIceCandidatesRemoved(IceCandidate[] candidates);
|
|
|
|
|
|
2013-07-10 00:45:36 +00:00
|
|
|
/** 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);
|
2013-07-12 16:04:50 +00:00
|
|
|
|
|
|
|
|
/** Triggered when a remote peer opens a DataChannel. */
|
|
|
|
|
public void onDataChannel(DataChannel dataChannel);
|
2014-01-13 22:04:12 +00:00
|
|
|
|
|
|
|
|
/** Triggered when renegotiation is necessary. */
|
|
|
|
|
public void onRenegotiationNeeded();
|
2013-07-10 00:45:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 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 + "]";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-30 12:35:24 -07:00
|
|
|
/** Java version of PeerConnectionInterface.IceTransportsType */
|
|
|
|
|
public enum IceTransportsType {
|
|
|
|
|
NONE, RELAY, NOHOST, ALL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Java version of PeerConnectionInterface.BundlePolicy */
|
|
|
|
|
public enum BundlePolicy {
|
|
|
|
|
BALANCED, MAXBUNDLE, MAXCOMPAT
|
|
|
|
|
};
|
|
|
|
|
|
2015-05-21 07:48:41 -07:00
|
|
|
/** Java version of PeerConnectionInterface.RtcpMuxPolicy */
|
|
|
|
|
public enum RtcpMuxPolicy {
|
|
|
|
|
NEGOTIATE, REQUIRE
|
|
|
|
|
};
|
2015-09-01 11:31:27 -07:00
|
|
|
|
2015-05-21 07:48:41 -07:00
|
|
|
/** Java version of PeerConnectionInterface.TcpCandidatePolicy */
|
2015-04-30 12:35:24 -07:00
|
|
|
public enum TcpCandidatePolicy {
|
|
|
|
|
ENABLED, DISABLED
|
|
|
|
|
};
|
|
|
|
|
|
2015-09-01 11:31:27 -07:00
|
|
|
/** Java version of rtc::KeyType */
|
|
|
|
|
public enum KeyType {
|
|
|
|
|
RSA, ECDSA
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-28 07:57:34 -07:00
|
|
|
/** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
|
|
|
|
|
public enum ContinualGatheringPolicy {
|
|
|
|
|
GATHER_ONCE, GATHER_CONTINUALLY
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-30 12:35:24 -07:00
|
|
|
/** Java version of PeerConnectionInterface.RTCConfiguration */
|
|
|
|
|
public static class RTCConfiguration {
|
|
|
|
|
public IceTransportsType iceTransportsType;
|
|
|
|
|
public List<IceServer> iceServers;
|
|
|
|
|
public BundlePolicy bundlePolicy;
|
2015-05-21 07:48:41 -07:00
|
|
|
public RtcpMuxPolicy rtcpMuxPolicy;
|
2015-04-30 12:35:24 -07:00
|
|
|
public TcpCandidatePolicy tcpCandidatePolicy;
|
2015-05-11 12:44:23 +02:00
|
|
|
public int audioJitterBufferMaxPackets;
|
2015-06-01 10:29:41 +02:00
|
|
|
public boolean audioJitterBufferFastAccelerate;
|
2015-09-01 09:53:56 -07:00
|
|
|
public int iceConnectionReceivingTimeout;
|
2015-12-04 12:24:03 -08:00
|
|
|
public int iceBackupCandidatePairPingInterval;
|
2015-09-01 11:31:27 -07:00
|
|
|
public KeyType keyType;
|
2015-09-28 07:57:34 -07:00
|
|
|
public ContinualGatheringPolicy continualGatheringPolicy;
|
2016-05-18 16:20:14 -07:00
|
|
|
public int iceCandidatePoolSize;
|
2015-04-30 12:35:24 -07:00
|
|
|
|
|
|
|
|
public RTCConfiguration(List<IceServer> iceServers) {
|
|
|
|
|
iceTransportsType = IceTransportsType.ALL;
|
|
|
|
|
bundlePolicy = BundlePolicy.BALANCED;
|
2015-05-21 07:48:41 -07:00
|
|
|
rtcpMuxPolicy = RtcpMuxPolicy.NEGOTIATE;
|
2015-04-30 12:35:24 -07:00
|
|
|
tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
|
|
|
|
|
this.iceServers = iceServers;
|
2015-05-11 12:44:23 +02:00
|
|
|
audioJitterBufferMaxPackets = 50;
|
2015-06-01 10:29:41 +02:00
|
|
|
audioJitterBufferFastAccelerate = false;
|
2015-09-01 09:53:56 -07:00
|
|
|
iceConnectionReceivingTimeout = -1;
|
2015-12-04 12:24:03 -08:00
|
|
|
iceBackupCandidatePairPingInterval = -1;
|
2015-09-01 11:31:27 -07:00
|
|
|
keyType = KeyType.ECDSA;
|
2015-09-28 07:57:34 -07:00
|
|
|
continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE;
|
2016-05-18 16:20:14 -07:00
|
|
|
iceCandidatePoolSize = 0;
|
2015-04-30 12:35:24 -07:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2013-07-10 00:45:36 +00:00
|
|
|
private final List<MediaStream> localStreams;
|
|
|
|
|
private final long nativePeerConnection;
|
|
|
|
|
private final long nativeObserver;
|
2015-10-06 12:29:25 -07:00
|
|
|
private List<RtpSender> senders;
|
|
|
|
|
private List<RtpReceiver> receivers;
|
2013-07-10 00:45:36 +00:00
|
|
|
|
|
|
|
|
PeerConnection(long nativePeerConnection, long nativeObserver) {
|
|
|
|
|
this.nativePeerConnection = nativePeerConnection;
|
|
|
|
|
this.nativeObserver = nativeObserver;
|
|
|
|
|
localStreams = new LinkedList<MediaStream>();
|
2015-10-06 12:29:25 -07:00
|
|
|
senders = new LinkedList<RtpSender>();
|
|
|
|
|
receivers = new LinkedList<RtpReceiver>();
|
2013-07-10 00:45:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// JsepInterface.
|
|
|
|
|
public native SessionDescription getLocalDescription();
|
|
|
|
|
|
|
|
|
|
public native SessionDescription getRemoteDescription();
|
|
|
|
|
|
2013-07-12 16:04:50 +00:00
|
|
|
public native DataChannel createDataChannel(
|
|
|
|
|
String label, DataChannel.Init init);
|
|
|
|
|
|
2013-07-10 00:45:36 +00:00
|
|
|
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);
|
|
|
|
|
|
2015-09-29 11:56:26 -07:00
|
|
|
public native boolean setConfiguration(RTCConfiguration config);
|
2013-07-10 00:45:36 +00:00
|
|
|
|
|
|
|
|
public boolean addIceCandidate(IceCandidate candidate) {
|
|
|
|
|
return nativeAddIceCandidate(
|
|
|
|
|
candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-14 11:59:18 -07:00
|
|
|
public boolean removeIceCandidates(final IceCandidate[] candidates) {
|
|
|
|
|
return nativeRemoveIceCandidates(candidates);
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-04 11:31:29 +00:00
|
|
|
public boolean addStream(MediaStream stream) {
|
|
|
|
|
boolean ret = nativeAddLocalStream(stream.nativeStream);
|
2013-07-10 00:45:36 +00:00
|
|
|
if (!ret) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
localStreams.add(stream);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void removeStream(MediaStream stream) {
|
|
|
|
|
nativeRemoveLocalStream(stream.nativeStream);
|
|
|
|
|
localStreams.remove(stream);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-18 16:58:44 -08:00
|
|
|
public RtpSender createSender(String kind, String stream_id) {
|
|
|
|
|
RtpSender new_sender = nativeCreateSender(kind, stream_id);
|
2015-12-02 11:27:40 -08:00
|
|
|
if (new_sender != null) {
|
|
|
|
|
senders.add(new_sender);
|
|
|
|
|
}
|
|
|
|
|
return new_sender;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-06 12:29:25 -07:00
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-10 00:45:36 +00:00
|
|
|
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) {
|
2013-08-12 23:26:21 +00:00
|
|
|
nativeRemoveLocalStream(stream.nativeStream);
|
2013-07-10 00:45:36 +00:00
|
|
|
stream.dispose();
|
|
|
|
|
}
|
|
|
|
|
localStreams.clear();
|
2015-10-06 12:29:25 -07:00
|
|
|
for (RtpSender sender : senders) {
|
|
|
|
|
sender.dispose();
|
|
|
|
|
}
|
|
|
|
|
senders.clear();
|
|
|
|
|
for (RtpReceiver receiver : receivers) {
|
|
|
|
|
receiver.dispose();
|
|
|
|
|
}
|
|
|
|
|
receivers.clear();
|
2013-07-10 00:45:36 +00:00
|
|
|
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);
|
|
|
|
|
|
2016-03-14 11:59:18 -07:00
|
|
|
private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
|
|
|
|
|
|
2014-11-04 11:31:29 +00:00
|
|
|
private native boolean nativeAddLocalStream(long nativeStream);
|
2013-07-10 00:45:36 +00:00
|
|
|
|
|
|
|
|
private native void nativeRemoveLocalStream(long nativeStream);
|
|
|
|
|
|
|
|
|
|
private native boolean nativeGetStats(
|
|
|
|
|
StatsObserver observer, long nativeTrack);
|
2015-10-06 12:29:25 -07:00
|
|
|
|
2015-12-18 16:58:44 -08:00
|
|
|
private native RtpSender nativeCreateSender(String kind, String stream_id);
|
2015-12-02 11:27:40 -08:00
|
|
|
|
2015-10-06 12:29:25 -07:00
|
|
|
private native List<RtpSender> nativeGetSenders();
|
|
|
|
|
|
|
|
|
|
private native List<RtpReceiver> nativeGetReceivers();
|
2013-07-10 00:45:36 +00:00
|
|
|
}
|