blob: 71a258e6c03d29bb03e0a352c60377648929cdbe [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
henrike@webrtc.org28e20752013-07-10 00:45:36 +000011package org.webrtc;
12
Magnus Jedvert6062f372017-11-16 16:53:12 +010013import java.util.ArrayList;
Sami Kalliomäki3e189a62017-11-24 11:13:39 +010014import java.util.Collections;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000015import java.util.List;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +010016import javax.annotation.Nullable;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017
18/**
19 * Java-land version of the PeerConnection APIs; wraps the C++ API
20 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the
21 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
22 * http://www.w3.org/TR/mediacapture-streams/
23 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +010024@JNINamespace("webrtc::jni")
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025public class PeerConnection {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000026 /** Tracks PeerConnectionInterface::IceGatheringState */
Magnus Jedvertba700f62017-12-04 13:43:27 +010027 public enum IceGatheringState {
28 NEW,
29 GATHERING,
30 COMPLETE;
31
32 @CalledByNative("IceGatheringState")
33 static IceGatheringState fromNativeIndex(int nativeIndex) {
34 return values()[nativeIndex];
35 }
36 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
38 /** Tracks PeerConnectionInterface::IceConnectionState */
39 public enum IceConnectionState {
sakalb6760f92016-09-29 04:12:44 -070040 NEW,
41 CHECKING,
42 CONNECTED,
43 COMPLETED,
44 FAILED,
45 DISCONNECTED,
Magnus Jedvertba700f62017-12-04 13:43:27 +010046 CLOSED;
47
48 @CalledByNative("IceConnectionState")
49 static IceConnectionState fromNativeIndex(int nativeIndex) {
50 return values()[nativeIndex];
51 }
sakalb6760f92016-09-29 04:12:44 -070052 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053
hnsl04833622017-01-09 08:35:45 -080054 /** Tracks PeerConnectionInterface::TlsCertPolicy */
55 public enum TlsCertPolicy {
56 TLS_CERT_POLICY_SECURE,
57 TLS_CERT_POLICY_INSECURE_NO_CHECK,
58 }
59
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060 /** Tracks PeerConnectionInterface::SignalingState */
61 public enum SignalingState {
sakalb6760f92016-09-29 04:12:44 -070062 STABLE,
63 HAVE_LOCAL_OFFER,
64 HAVE_LOCAL_PRANSWER,
65 HAVE_REMOTE_OFFER,
66 HAVE_REMOTE_PRANSWER,
Magnus Jedvertba700f62017-12-04 13:43:27 +010067 CLOSED;
68
69 @CalledByNative("SignalingState")
70 static SignalingState fromNativeIndex(int nativeIndex) {
71 return values()[nativeIndex];
72 }
sakalb6760f92016-09-29 04:12:44 -070073 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074
75 /** Java version of PeerConnectionObserver. */
76 public static interface Observer {
77 /** Triggered when the SignalingState changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010078 @CalledByNative("Observer") void onSignalingChange(SignalingState newState);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000079
80 /** Triggered when the IceConnectionState changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010081 @CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000082
Peter Thatcher54360512015-07-08 11:08:35 -070083 /** Triggered when the ICE connection receiving status changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010084 @CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving);
Peter Thatcher54360512015-07-08 11:08:35 -070085
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 /** Triggered when the IceGatheringState changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010087 @CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088
89 /** Triggered when a new ICE candidate has been found. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010090 @CalledByNative("Observer") void onIceCandidate(IceCandidate candidate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091
Honghai Zhang7fb69db2016-03-14 11:59:18 -070092 /** Triggered when some ICE candidates have been removed. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010093 @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates);
Honghai Zhang7fb69db2016-03-14 11:59:18 -070094
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095 /** Triggered when media is received on a new stream from remote peer. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010096 @CalledByNative("Observer") void onAddStream(MediaStream stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097
98 /** Triggered when a remote peer close a stream. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010099 @CalledByNative("Observer") void onRemoveStream(MediaStream stream);
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000100
101 /** Triggered when a remote peer opens a DataChannel. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100102 @CalledByNative("Observer") void onDataChannel(DataChannel dataChannel);
fischman@webrtc.orgd7568a02014-01-13 22:04:12 +0000103
104 /** Triggered when renegotiation is necessary. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100105 @CalledByNative("Observer") void onRenegotiationNeeded();
zhihuangdcccda72016-12-21 14:08:03 -0800106
107 /**
108 * Triggered when a new track is signaled by the remote peer, as a result of
109 * setRemoteDescription.
110 */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100111 @CalledByNative("Observer") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams);
Seth Hampson31dbc242018-05-07 09:28:19 -0700112
113 /**
114 * Triggered when the signaling from SetRemoteDescription indicates that a transceiver
115 * will be receiving media from a remote endpoint. This is only called if UNIFIED_PLAN
116 * semantics are specified. The transceiver will be disposed automatically.
117 */
118 @CalledByNative("Observer") default void onTrack(RtpTransceiver transceiver){};
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119 }
120
121 /** Java version of PeerConnectionInterface.IceServer. */
122 public static class IceServer {
Emad Omaradab1d2d2017-06-16 15:43:11 -0700123 // List of URIs associated with this server. Valid formats are described
124 // in RFC7064 and RFC7065, and more may be added in the future. The "host"
125 // part of the URI may contain either an IP address or a hostname.
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700126 @Deprecated public final String uri;
127 public final List<String> urls;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000128 public final String username;
129 public final String password;
hnsl04833622017-01-09 08:35:45 -0800130 public final TlsCertPolicy tlsCertPolicy;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131
Emad Omaradab1d2d2017-06-16 15:43:11 -0700132 // If the URIs in |urls| only contain IP addresses, this field can be used
133 // to indicate the hostname, which may be necessary for TLS (using the SNI
134 // extension). If |urls| itself contains the hostname, this isn't
135 // necessary.
136 public final String hostname;
137
Diogo Real1dca9d52017-08-29 12:18:32 -0700138 // List of protocols to be used in the TLS ALPN extension.
139 public final List<String> tlsAlpnProtocols;
140
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700141 // List of elliptic curves to be used in the TLS elliptic curves extension.
142 // Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
143 public final List<String> tlsEllipticCurves;
144
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 /** Convenience constructor for STUN servers. */
Diogo Real05ea2b32017-08-31 00:12:58 -0700146 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147 public IceServer(String uri) {
148 this(uri, "", "");
149 }
150
Diogo Real05ea2b32017-08-31 00:12:58 -0700151 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152 public IceServer(String uri, String username, String password) {
hnsl04833622017-01-09 08:35:45 -0800153 this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE);
154 }
155
Diogo Real05ea2b32017-08-31 00:12:58 -0700156 @Deprecated
hnsl04833622017-01-09 08:35:45 -0800157 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) {
Emad Omaradab1d2d2017-06-16 15:43:11 -0700158 this(uri, username, password, tlsCertPolicy, "");
159 }
160
Diogo Real05ea2b32017-08-31 00:12:58 -0700161 @Deprecated
Emad Omaradab1d2d2017-06-16 15:43:11 -0700162 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
163 String hostname) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700164 this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null,
165 null);
Diogo Real1dca9d52017-08-29 12:18:32 -0700166 }
167
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700168 private IceServer(String uri, List<String> urls, String username, String password,
169 TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols,
170 List<String> tlsEllipticCurves) {
171 if (uri == null || urls == null || urls.isEmpty()) {
172 throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()");
173 }
174 for (String it : urls) {
175 if (it == null) {
176 throw new IllegalArgumentException("urls element is null: " + urls);
177 }
178 }
179 if (username == null) {
180 throw new IllegalArgumentException("username == null");
181 }
182 if (password == null) {
183 throw new IllegalArgumentException("password == null");
184 }
185 if (hostname == null) {
186 throw new IllegalArgumentException("hostname == null");
187 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000188 this.uri = uri;
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700189 this.urls = urls;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 this.username = username;
191 this.password = password;
hnsl04833622017-01-09 08:35:45 -0800192 this.tlsCertPolicy = tlsCertPolicy;
Emad Omaradab1d2d2017-06-16 15:43:11 -0700193 this.hostname = hostname;
Diogo Real1dca9d52017-08-29 12:18:32 -0700194 this.tlsAlpnProtocols = tlsAlpnProtocols;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700195 this.tlsEllipticCurves = tlsEllipticCurves;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000196 }
197
Sami Kalliomäkibde473e2017-10-30 13:34:41 +0100198 @Override
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 public String toString() {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700200 return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700201 + "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
Diogo Real1dca9d52017-08-29 12:18:32 -0700202 }
203
204 public static Builder builder(String uri) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700205 return new Builder(Collections.singletonList(uri));
206 }
207
208 public static Builder builder(List<String> urls) {
209 return new Builder(urls);
Diogo Real1dca9d52017-08-29 12:18:32 -0700210 }
211
212 public static class Builder {
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100213 @Nullable private final List<String> urls;
Diogo Real1dca9d52017-08-29 12:18:32 -0700214 private String username = "";
215 private String password = "";
216 private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
217 private String hostname = "";
218 private List<String> tlsAlpnProtocols;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700219 private List<String> tlsEllipticCurves;
Diogo Real1dca9d52017-08-29 12:18:32 -0700220
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700221 private Builder(List<String> urls) {
222 if (urls == null || urls.isEmpty()) {
223 throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls);
224 }
225 this.urls = urls;
Diogo Real1dca9d52017-08-29 12:18:32 -0700226 }
227
228 public Builder setUsername(String username) {
229 this.username = username;
230 return this;
231 }
232
233 public Builder setPassword(String password) {
234 this.password = password;
235 return this;
236 }
237
238 public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) {
239 this.tlsCertPolicy = tlsCertPolicy;
240 return this;
241 }
242
243 public Builder setHostname(String hostname) {
244 this.hostname = hostname;
245 return this;
246 }
247
248 public Builder setTlsAlpnProtocols(List<String> tlsAlpnProtocols) {
249 this.tlsAlpnProtocols = tlsAlpnProtocols;
250 return this;
251 }
252
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700253 public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
254 this.tlsEllipticCurves = tlsEllipticCurves;
255 return this;
256 }
257
Diogo Real1dca9d52017-08-29 12:18:32 -0700258 public IceServer createIceServer() {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700259 return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname,
260 tlsAlpnProtocols, tlsEllipticCurves);
Diogo Real1dca9d52017-08-29 12:18:32 -0700261 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 }
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100263
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100264 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100265 @CalledByNative("IceServer")
266 List<String> getUrls() {
267 return urls;
268 }
269
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100270 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100271 @CalledByNative("IceServer")
272 String getUsername() {
273 return username;
274 }
275
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100276 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100277 @CalledByNative("IceServer")
278 String getPassword() {
279 return password;
280 }
281
282 @CalledByNative("IceServer")
283 TlsCertPolicy getTlsCertPolicy() {
284 return tlsCertPolicy;
285 }
286
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100287 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100288 @CalledByNative("IceServer")
289 String getHostname() {
290 return hostname;
291 }
292
293 @CalledByNative("IceServer")
294 List<String> getTlsAlpnProtocols() {
295 return tlsAlpnProtocols;
296 }
297
298 @CalledByNative("IceServer")
299 List<String> getTlsEllipticCurves() {
300 return tlsEllipticCurves;
301 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302 }
303
Jiayang Liucac1b382015-04-30 12:35:24 -0700304 /** Java version of PeerConnectionInterface.IceTransportsType */
sakalb6760f92016-09-29 04:12:44 -0700305 public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }
Jiayang Liucac1b382015-04-30 12:35:24 -0700306
307 /** Java version of PeerConnectionInterface.BundlePolicy */
sakalb6760f92016-09-29 04:12:44 -0700308 public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }
Jiayang Liucac1b382015-04-30 12:35:24 -0700309
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700310 /** Java version of PeerConnectionInterface.RtcpMuxPolicy */
sakalb6760f92016-09-29 04:12:44 -0700311 public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }
glaznev97579a42015-09-01 11:31:27 -0700312
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700313 /** Java version of PeerConnectionInterface.TcpCandidatePolicy */
sakalb6760f92016-09-29 04:12:44 -0700314 public enum TcpCandidatePolicy { ENABLED, DISABLED }
Jiayang Liucac1b382015-04-30 12:35:24 -0700315
honghaiz60347052016-05-31 18:29:12 -0700316 /** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
sakalb6760f92016-09-29 04:12:44 -0700317 public enum CandidateNetworkPolicy { ALL, LOW_COST }
honghaiz60347052016-05-31 18:29:12 -0700318
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800319 // Keep in sync with webrtc/rtc_base/network_constants.h.
320 public enum AdapterType {
321 UNKNOWN,
322 ETHERNET,
323 WIFI,
324 CELLULAR,
325 VPN,
326 LOOPBACK,
327 }
328
glaznev97579a42015-09-01 11:31:27 -0700329 /** Java version of rtc::KeyType */
sakalb6760f92016-09-29 04:12:44 -0700330 public enum KeyType { RSA, ECDSA }
glaznev97579a42015-09-01 11:31:27 -0700331
honghaiz1f429e32015-09-28 07:57:34 -0700332 /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
sakalb6760f92016-09-29 04:12:44 -0700333 public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }
honghaiz1f429e32015-09-28 07:57:34 -0700334
Steve Antond960a0c2017-07-17 12:33:07 -0700335 /** Java version of rtc::IntervalRange */
336 public static class IntervalRange {
337 private final int min;
338 private final int max;
339
340 public IntervalRange(int min, int max) {
341 this.min = min;
342 this.max = max;
343 }
344
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100345 @CalledByNative("IntervalRange")
Steve Antond960a0c2017-07-17 12:33:07 -0700346 public int getMin() {
347 return min;
348 }
349
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100350 @CalledByNative("IntervalRange")
Steve Antond960a0c2017-07-17 12:33:07 -0700351 public int getMax() {
352 return max;
353 }
354 }
355
Seth Hampsonc384e142018-03-06 15:47:10 -0800356 /**
357 * Java version of webrtc::SdpSemantics.
358 *
359 * Configure the SDP semantics used by this PeerConnection. Note that the
360 * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The
361 * RtpTransceiver API is only available with UNIFIED_PLAN semantics.
362 *
363 * <p>PLAN_B will cause PeerConnection to create offers and answers with at
364 * most one audio and one video m= section with multiple RtpSenders and
365 * RtpReceivers specified as multiple a=ssrc lines within the section. This
366 * will also cause PeerConnection to ignore all but the first m= section of
367 * the same media type.
368 *
369 * <p>UNIFIED_PLAN will cause PeerConnection to create offers and answers with
370 * multiple m= sections where each m= section maps to one RtpSender and one
371 * RtpReceiver (an RtpTransceiver), either both audio or both video. This
372 * will also cause PeerConnection to ignore all but the first a=ssrc lines
373 * that form a Plan B stream.
374 *
375 * <p>For users who wish to send multiple audio/video streams and need to stay
376 * interoperable with legacy WebRTC implementations, specify PLAN_B.
377 *
378 * <p>For users who wish to send multiple audio/video streams and/or wish to
379 * use the new RtpTransceiver API, specify UNIFIED_PLAN.
380 */
381 public enum SdpSemantics { PLAN_B, UNIFIED_PLAN }
382
Jiayang Liucac1b382015-04-30 12:35:24 -0700383 /** Java version of PeerConnectionInterface.RTCConfiguration */
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800384 // TODO(qingsi): Resolve the naming inconsistency of fields with/without units.
Jiayang Liucac1b382015-04-30 12:35:24 -0700385 public static class RTCConfiguration {
386 public IceTransportsType iceTransportsType;
387 public List<IceServer> iceServers;
388 public BundlePolicy bundlePolicy;
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700389 public RtcpMuxPolicy rtcpMuxPolicy;
Jiayang Liucac1b382015-04-30 12:35:24 -0700390 public TcpCandidatePolicy tcpCandidatePolicy;
honghaiz60347052016-05-31 18:29:12 -0700391 public CandidateNetworkPolicy candidateNetworkPolicy;
Henrik Lundin64dad832015-05-11 12:44:23 +0200392 public int audioJitterBufferMaxPackets;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200393 public boolean audioJitterBufferFastAccelerate;
honghaiz4edc39c2015-09-01 09:53:56 -0700394 public int iceConnectionReceivingTimeout;
Honghai Zhang381b4212015-12-04 12:24:03 -0800395 public int iceBackupCandidatePairPingInterval;
glaznev97579a42015-09-01 11:31:27 -0700396 public KeyType keyType;
honghaiz1f429e32015-09-28 07:57:34 -0700397 public ContinualGatheringPolicy continualGatheringPolicy;
deadbeefbe0c96f2016-05-18 16:20:14 -0700398 public int iceCandidatePoolSize;
Honghai Zhangd78ecf72016-07-01 14:40:40 -0700399 public boolean pruneTurnPorts;
Taylor Brandstettere9851112016-07-01 11:11:13 -0700400 public boolean presumeWritableWhenFullyRelayed;
Qingsi Wange6826d22018-03-08 14:55:14 -0800401 // The following fields define intervals in milliseconds at which ICE
402 // connectivity checks are sent.
403 //
404 // We consider ICE is "strongly connected" for an agent when there is at
405 // least one candidate pair that currently succeeds in connectivity check
406 // from its direction i.e. sending a ping and receives a ping response, AND
407 // all candidate pairs have sent a minimum number of pings for connectivity
408 // (this number is implementation-specific). Otherwise, ICE is considered in
409 // "weak connectivity".
410 //
411 // Note that the above notion of strong and weak connectivity is not defined
412 // in RFC 5245, and they apply to our current ICE implementation only.
413 //
414 // 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to
415 // ALL candidate pairs when ICE is strongly connected,
416 // 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL
417 // pairs when ICE is weakly connected, and
418 // 3) iceCheckMinInterval defines the minimal interval (equivalently the
419 // maximum rate) that overrides the above two intervals when either of them
420 // is less.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100421 @Nullable public Integer iceCheckIntervalStrongConnectivityMs;
422 @Nullable public Integer iceCheckIntervalWeakConnectivityMs;
423 @Nullable public Integer iceCheckMinInterval;
Qingsi Wang22e623a2018-03-13 10:53:57 -0700424 // The time period in milliseconds for which a candidate pair must wait for response to
425 // connectivitiy checks before it becomes unwritable.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100426 @Nullable public Integer iceUnwritableTimeMs;
Qingsi Wang22e623a2018-03-13 10:53:57 -0700427 // The minimum number of connectivity checks that a candidate pair must sent without receiving
428 // response before it becomes unwritable.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100429 @Nullable public Integer iceUnwritableMinChecks;
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800430 // The interval in milliseconds at which STUN candidates will resend STUN binding requests
431 // to keep NAT bindings open.
432 // The default value in the implementation is used if this field is null.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100433 @Nullable public Integer stunCandidateKeepaliveIntervalMs;
zhihuangb09b3f92017-03-07 14:40:51 -0800434 public boolean disableIPv6OnWifi;
deadbeef28e29192017-07-27 09:14:38 -0700435 // By default, PeerConnection will use a limited number of IPv6 network
436 // interfaces, in order to avoid too many ICE candidate pairs being created
437 // and delaying ICE completion.
438 //
439 // Can be set to Integer.MAX_VALUE to effectively disable the limit.
440 public int maxIPv6Networks;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100441 @Nullable public IntervalRange iceRegatherIntervalRange;
Jiayang Liucac1b382015-04-30 12:35:24 -0700442
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100443 // These values will be overridden by MediaStream constraints if deprecated constraints-based
444 // create peerconnection interface is used.
445 public boolean disableIpv6;
446 public boolean enableDscp;
447 public boolean enableCpuOveruseDetection;
448 public boolean enableRtpDataChannel;
449 public boolean suspendBelowMinBitrate;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100450 @Nullable public Integer screencastMinBitrate;
451 @Nullable public Boolean combinedAudioVideoBwe;
452 @Nullable public Boolean enableDtlsSrtp;
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800453 // Use "Unknown" to represent no preference of adapter types, not the
454 // preference of adapters of unknown types.
455 public AdapterType networkPreference;
Seth Hampsonc384e142018-03-06 15:47:10 -0800456 public SdpSemantics sdpSemantics;
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100457
Jonas Orelandbdcee282017-10-10 14:01:40 +0200458 // This is an optional wrapper for the C++ webrtc::TurnCustomizer.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100459 @Nullable public TurnCustomizer turnCustomizer;
Jonas Orelandbdcee282017-10-10 14:01:40 +0200460
deadbeef28e29192017-07-27 09:14:38 -0700461 // TODO(deadbeef): Instead of duplicating the defaults here, we should do
462 // something to pick up the defaults from C++. The Objective-C equivalent
463 // of RTCConfiguration does that.
Jiayang Liucac1b382015-04-30 12:35:24 -0700464 public RTCConfiguration(List<IceServer> iceServers) {
465 iceTransportsType = IceTransportsType.ALL;
466 bundlePolicy = BundlePolicy.BALANCED;
zhihuang4dfb8ce2016-11-23 10:30:12 -0800467 rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE;
Jiayang Liucac1b382015-04-30 12:35:24 -0700468 tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
Sami Kalliomäki9828beb2017-10-26 16:21:22 +0200469 candidateNetworkPolicy = CandidateNetworkPolicy.ALL;
Jiayang Liucac1b382015-04-30 12:35:24 -0700470 this.iceServers = iceServers;
Henrik Lundin64dad832015-05-11 12:44:23 +0200471 audioJitterBufferMaxPackets = 50;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200472 audioJitterBufferFastAccelerate = false;
honghaiz4edc39c2015-09-01 09:53:56 -0700473 iceConnectionReceivingTimeout = -1;
Honghai Zhang381b4212015-12-04 12:24:03 -0800474 iceBackupCandidatePairPingInterval = -1;
glaznev97579a42015-09-01 11:31:27 -0700475 keyType = KeyType.ECDSA;
honghaiz1f429e32015-09-28 07:57:34 -0700476 continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE;
deadbeefbe0c96f2016-05-18 16:20:14 -0700477 iceCandidatePoolSize = 0;
Honghai Zhangd78ecf72016-07-01 14:40:40 -0700478 pruneTurnPorts = false;
Taylor Brandstettere9851112016-07-01 11:11:13 -0700479 presumeWritableWhenFullyRelayed = false;
Qingsi Wange6826d22018-03-08 14:55:14 -0800480 iceCheckIntervalStrongConnectivityMs = null;
481 iceCheckIntervalWeakConnectivityMs = null;
skvlad51072462017-02-02 11:50:14 -0800482 iceCheckMinInterval = null;
Qingsi Wang22e623a2018-03-13 10:53:57 -0700483 iceUnwritableTimeMs = null;
484 iceUnwritableMinChecks = null;
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800485 stunCandidateKeepaliveIntervalMs = null;
zhihuangb09b3f92017-03-07 14:40:51 -0800486 disableIPv6OnWifi = false;
deadbeef28e29192017-07-27 09:14:38 -0700487 maxIPv6Networks = 5;
Steve Antond960a0c2017-07-17 12:33:07 -0700488 iceRegatherIntervalRange = null;
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100489 disableIpv6 = false;
490 enableDscp = false;
491 enableCpuOveruseDetection = true;
492 enableRtpDataChannel = false;
493 suspendBelowMinBitrate = false;
494 screencastMinBitrate = null;
495 combinedAudioVideoBwe = null;
496 enableDtlsSrtp = null;
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800497 networkPreference = AdapterType.UNKNOWN;
Seth Hampsonc384e142018-03-06 15:47:10 -0800498 sdpSemantics = SdpSemantics.PLAN_B;
Jiayang Liucac1b382015-04-30 12:35:24 -0700499 }
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100500
501 @CalledByNative("RTCConfiguration")
502 IceTransportsType getIceTransportsType() {
503 return iceTransportsType;
504 }
505
506 @CalledByNative("RTCConfiguration")
507 List<IceServer> getIceServers() {
508 return iceServers;
509 }
510
511 @CalledByNative("RTCConfiguration")
512 BundlePolicy getBundlePolicy() {
513 return bundlePolicy;
514 }
515
516 @CalledByNative("RTCConfiguration")
517 RtcpMuxPolicy getRtcpMuxPolicy() {
518 return rtcpMuxPolicy;
519 }
520
521 @CalledByNative("RTCConfiguration")
522 TcpCandidatePolicy getTcpCandidatePolicy() {
523 return tcpCandidatePolicy;
524 }
525
526 @CalledByNative("RTCConfiguration")
527 CandidateNetworkPolicy getCandidateNetworkPolicy() {
528 return candidateNetworkPolicy;
529 }
530
531 @CalledByNative("RTCConfiguration")
532 int getAudioJitterBufferMaxPackets() {
533 return audioJitterBufferMaxPackets;
534 }
535
536 @CalledByNative("RTCConfiguration")
537 boolean getAudioJitterBufferFastAccelerate() {
538 return audioJitterBufferFastAccelerate;
539 }
540
541 @CalledByNative("RTCConfiguration")
542 int getIceConnectionReceivingTimeout() {
543 return iceConnectionReceivingTimeout;
544 }
545
546 @CalledByNative("RTCConfiguration")
547 int getIceBackupCandidatePairPingInterval() {
548 return iceBackupCandidatePairPingInterval;
549 }
550
551 @CalledByNative("RTCConfiguration")
552 KeyType getKeyType() {
553 return keyType;
554 }
555
556 @CalledByNative("RTCConfiguration")
557 ContinualGatheringPolicy getContinualGatheringPolicy() {
558 return continualGatheringPolicy;
559 }
560
561 @CalledByNative("RTCConfiguration")
562 int getIceCandidatePoolSize() {
563 return iceCandidatePoolSize;
564 }
565
566 @CalledByNative("RTCConfiguration")
567 boolean getPruneTurnPorts() {
568 return pruneTurnPorts;
569 }
570
571 @CalledByNative("RTCConfiguration")
572 boolean getPresumeWritableWhenFullyRelayed() {
573 return presumeWritableWhenFullyRelayed;
574 }
575
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100576 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100577 @CalledByNative("RTCConfiguration")
Qingsi Wange6826d22018-03-08 14:55:14 -0800578 Integer getIceCheckIntervalStrongConnectivity() {
579 return iceCheckIntervalStrongConnectivityMs;
580 }
581
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100582 @Nullable
Qingsi Wange6826d22018-03-08 14:55:14 -0800583 @CalledByNative("RTCConfiguration")
584 Integer getIceCheckIntervalWeakConnectivity() {
585 return iceCheckIntervalWeakConnectivityMs;
586 }
587
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100588 @Nullable
Qingsi Wange6826d22018-03-08 14:55:14 -0800589 @CalledByNative("RTCConfiguration")
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100590 Integer getIceCheckMinInterval() {
591 return iceCheckMinInterval;
592 }
593
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100594 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100595 @CalledByNative("RTCConfiguration")
Qingsi Wang22e623a2018-03-13 10:53:57 -0700596 Integer getIceUnwritableTimeout() {
597 return iceUnwritableTimeMs;
598 }
599
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100600 @Nullable
Qingsi Wang22e623a2018-03-13 10:53:57 -0700601 @CalledByNative("RTCConfiguration")
602 Integer getIceUnwritableMinChecks() {
603 return iceUnwritableMinChecks;
604 }
605
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100606 @Nullable
Qingsi Wang22e623a2018-03-13 10:53:57 -0700607 @CalledByNative("RTCConfiguration")
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800608 Integer getStunCandidateKeepaliveInterval() {
609 return stunCandidateKeepaliveIntervalMs;
610 }
611
612 @CalledByNative("RTCConfiguration")
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100613 boolean getDisableIPv6OnWifi() {
614 return disableIPv6OnWifi;
615 }
616
617 @CalledByNative("RTCConfiguration")
618 int getMaxIPv6Networks() {
619 return maxIPv6Networks;
620 }
621
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100622 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100623 @CalledByNative("RTCConfiguration")
624 IntervalRange getIceRegatherIntervalRange() {
625 return iceRegatherIntervalRange;
626 }
627
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100628 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100629 @CalledByNative("RTCConfiguration")
630 TurnCustomizer getTurnCustomizer() {
631 return turnCustomizer;
632 }
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100633
634 @CalledByNative("RTCConfiguration")
635 boolean getDisableIpv6() {
636 return disableIpv6;
637 }
638
639 @CalledByNative("RTCConfiguration")
640 boolean getEnableDscp() {
641 return enableDscp;
642 }
643
644 @CalledByNative("RTCConfiguration")
645 boolean getEnableCpuOveruseDetection() {
646 return enableCpuOveruseDetection;
647 }
648
649 @CalledByNative("RTCConfiguration")
650 boolean getEnableRtpDataChannel() {
651 return enableRtpDataChannel;
652 }
653
654 @CalledByNative("RTCConfiguration")
655 boolean getSuspendBelowMinBitrate() {
656 return suspendBelowMinBitrate;
657 }
658
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100659 @Nullable
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100660 @CalledByNative("RTCConfiguration")
661 Integer getScreencastMinBitrate() {
662 return screencastMinBitrate;
663 }
664
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100665 @Nullable
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100666 @CalledByNative("RTCConfiguration")
667 Boolean getCombinedAudioVideoBwe() {
668 return combinedAudioVideoBwe;
669 }
670
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100671 @Nullable
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100672 @CalledByNative("RTCConfiguration")
673 Boolean getEnableDtlsSrtp() {
674 return enableDtlsSrtp;
675 }
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800676
677 @CalledByNative("RTCConfiguration")
678 AdapterType getNetworkPreference() {
679 return networkPreference;
680 }
Seth Hampsonc384e142018-03-06 15:47:10 -0800681
682 @CalledByNative("RTCConfiguration")
683 SdpSemantics getSdpSemantics() {
684 return sdpSemantics;
685 }
Jiayang Liucac1b382015-04-30 12:35:24 -0700686 };
687
Magnus Jedvert6062f372017-11-16 16:53:12 +0100688 private final List<MediaStream> localStreams = new ArrayList<>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689 private final long nativePeerConnection;
Magnus Jedvert6062f372017-11-16 16:53:12 +0100690 private List<RtpSender> senders = new ArrayList<>();
691 private List<RtpReceiver> receivers = new ArrayList<>();
Seth Hampsonc384e142018-03-06 15:47:10 -0800692 private List<RtpTransceiver> transceivers = new ArrayList<>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693
Sami Kalliomäki1ece1ed2017-12-20 11:59:22 +0100694 /**
695 * Wraps a PeerConnection created by the factory. Can be used by clients that want to implement
696 * their PeerConnection creation in JNI.
697 */
698 public PeerConnection(NativePeerConnectionFactory factory) {
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +0100699 this(factory.createNativePeerConnection());
Sami Kalliomäki1ece1ed2017-12-20 11:59:22 +0100700 }
701
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +0100702 PeerConnection(long nativePeerConnection) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 this.nativePeerConnection = nativePeerConnection;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704 }
705
706 // JsepInterface.
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100707 public SessionDescription getLocalDescription() {
708 return nativeGetLocalDescription();
709 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100711 public SessionDescription getRemoteDescription() {
712 return nativeGetRemoteDescription();
713 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100715 public DataChannel createDataChannel(String label, DataChannel.Init init) {
716 return nativeCreateDataChannel(label, init);
717 }
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000718
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100719 public void createOffer(SdpObserver observer, MediaConstraints constraints) {
720 nativeCreateOffer(observer, constraints);
721 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100723 public void createAnswer(SdpObserver observer, MediaConstraints constraints) {
724 nativeCreateAnswer(observer, constraints);
725 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100727 public void setLocalDescription(SdpObserver observer, SessionDescription sdp) {
728 nativeSetLocalDescription(observer, sdp);
729 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100731 public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) {
732 nativeSetRemoteDescription(observer, sdp);
733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734
Seth Hampsonc384e142018-03-06 15:47:10 -0800735 /**
736 * Enables/disables playout of received audio streams. Enabled by default.
737 *
738 * Note that even if playout is enabled, streams will only be played out if
739 * the appropriate SDP is also applied. The main purpose of this API is to
740 * be able to control the exact time when audio playout starts.
741 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100742 public void setAudioPlayout(boolean playout) {
743 nativeSetAudioPlayout(playout);
744 }
henrika5f6bf242017-11-01 11:06:56 +0100745
Seth Hampsonc384e142018-03-06 15:47:10 -0800746 /**
747 * Enables/disables recording of transmitted audio streams. Enabled by default.
748 *
749 * Note that even if recording is enabled, streams will only be recorded if
750 * the appropriate SDP is also applied. The main purpose of this API is to
751 * be able to control the exact time when audio recording starts.
752 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100753 public void setAudioRecording(boolean recording) {
754 nativeSetAudioRecording(recording);
755 }
henrika5f6bf242017-11-01 11:06:56 +0100756
deadbeef5d0b6d82017-01-09 16:05:28 -0800757 public boolean setConfiguration(RTCConfiguration config) {
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +0100758 return nativeSetConfiguration(config);
deadbeef5d0b6d82017-01-09 16:05:28 -0800759 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760
761 public boolean addIceCandidate(IceCandidate candidate) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100762 return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763 }
764
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700765 public boolean removeIceCandidates(final IceCandidate[] candidates) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100766 return nativeRemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700767 }
768
Seth Hampsonc384e142018-03-06 15:47:10 -0800769 /**
770 * Adds a new MediaStream to be sent on this peer connection.
771 * Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please
772 * use addTrack instead.
773 */
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000774 public boolean addStream(MediaStream stream) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100775 boolean ret = nativeAddLocalStream(stream.nativeStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 if (!ret) {
777 return false;
778 }
779 localStreams.add(stream);
780 return true;
781 }
782
Seth Hampsonc384e142018-03-06 15:47:10 -0800783 /**
784 * Removes the given media stream from this peer connection.
785 * This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use
786 * removeTrack instead.
787 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 public void removeStream(MediaStream stream) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100789 nativeRemoveLocalStream(stream.nativeStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 localStreams.remove(stream);
791 }
792
deadbeef7a246882017-08-09 08:40:10 -0700793 /**
794 * Creates an RtpSender without a track.
Seth Hampsonc384e142018-03-06 15:47:10 -0800795 *
796 * <p>This method allows an application to cause the PeerConnection to negotiate
deadbeef7a246882017-08-09 08:40:10 -0700797 * sending/receiving a specific media type, but without having a track to
798 * send yet.
Seth Hampsonc384e142018-03-06 15:47:10 -0800799 *
800 * <p>When the application does want to begin sending a track, it can call
deadbeef7a246882017-08-09 08:40:10 -0700801 * RtpSender.setTrack, which doesn't require any additional SDP negotiation.
Seth Hampsonc384e142018-03-06 15:47:10 -0800802 *
803 * <p>Example use:
deadbeef7a246882017-08-09 08:40:10 -0700804 * <pre>
805 * {@code
806 * audioSender = pc.createSender("audio", "stream1");
807 * videoSender = pc.createSender("video", "stream1");
808 * // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate
809 * // media parameters....
810 * // Later, when the endpoint is ready to actually begin sending:
811 * audioSender.setTrack(audioTrack, false);
812 * videoSender.setTrack(videoTrack, false);
813 * }
814 * </pre>
Seth Hampsonc384e142018-03-06 15:47:10 -0800815 * <p>Note: This corresponds most closely to "addTransceiver" in the official
deadbeef7a246882017-08-09 08:40:10 -0700816 * WebRTC API, in that it creates a sender without a track. It was
817 * implemented before addTransceiver because it provides useful
818 * functionality, and properly implementing transceivers would have required
819 * a great deal more work.
820 *
Seth Hampsonc384e142018-03-06 15:47:10 -0800821 * <p>Note: This is only available with SdpSemantics.PLAN_B specified. Please use
822 * addTransceiver instead.
823 *
deadbeef7a246882017-08-09 08:40:10 -0700824 * @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or
825 * "video").
826 * @param stream_id The ID of the MediaStream that this sender's track will
827 * be associated with when SDP is applied to the remote
828 * PeerConnection. If createSender is used to create an
829 * audio and video sender that should be synchronized, they
830 * should use the same stream ID.
831 * @return A new RtpSender object if successful, or null otherwise.
832 */
deadbeefbd7d8f72015-12-18 16:58:44 -0800833 public RtpSender createSender(String kind, String stream_id) {
Seth Hampsonc384e142018-03-06 15:47:10 -0800834 RtpSender newSender = nativeCreateSender(kind, stream_id);
835 if (newSender != null) {
836 senders.add(newSender);
deadbeefee524f72015-12-02 11:27:40 -0800837 }
Seth Hampsonc384e142018-03-06 15:47:10 -0800838 return newSender;
deadbeefee524f72015-12-02 11:27:40 -0800839 }
840
Seth Hampsonc384e142018-03-06 15:47:10 -0800841 /**
842 * Gets all RtpSenders associated with this peer connection.
843 * Note that calling getSenders will dispose of the senders previously
844 * returned.
845 */
deadbeef4139c0f2015-10-06 12:29:25 -0700846 public List<RtpSender> getSenders() {
847 for (RtpSender sender : senders) {
848 sender.dispose();
849 }
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100850 senders = nativeGetSenders();
deadbeef4139c0f2015-10-06 12:29:25 -0700851 return Collections.unmodifiableList(senders);
852 }
853
Seth Hampsonc384e142018-03-06 15:47:10 -0800854 /**
855 * Gets all RtpReceivers associated with this peer connection.
856 * Note that calling getReceivers will dispose of the receivers previously
857 * returned.
858 */
deadbeef4139c0f2015-10-06 12:29:25 -0700859 public List<RtpReceiver> getReceivers() {
860 for (RtpReceiver receiver : receivers) {
861 receiver.dispose();
862 }
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100863 receivers = nativeGetReceivers();
deadbeef4139c0f2015-10-06 12:29:25 -0700864 return Collections.unmodifiableList(receivers);
865 }
866
Seth Hampsonc384e142018-03-06 15:47:10 -0800867 /**
868 * Gets all RtpTransceivers associated with this peer connection.
869 * Note that calling getTransceivers will dispose of the transceivers previously
870 * returned.
871 * Note: This is only available with SdpSemantics.UNIFIED_PLAN specified.
872 */
873 public List<RtpTransceiver> getTransceivers() {
874 for (RtpTransceiver transceiver : transceivers) {
875 transceiver.dispose();
876 }
877 transceivers = nativeGetTransceivers();
878 return Collections.unmodifiableList(transceivers);
879 }
880
881 /**
882 * Adds a new media stream track to be sent on this peer connection, and returns
883 * the newly created RtpSender. If streamIds are specified, the RtpSender will
884 * be associated with the streams specified in the streamIds list.
885 *
886 * @throws IllegalStateException if an error accors in C++ addTrack.
887 * An error can occur if:
888 * - A sender already exists for the track.
889 * - The peer connection is closed.
890 */
891 public RtpSender addTrack(MediaStreamTrack track) {
892 return addTrack(track, Collections.emptyList());
893 }
894
895 public RtpSender addTrack(MediaStreamTrack track, List<String> streamIds) {
896 if (track == null || streamIds == null) {
897 throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
898 }
899 RtpSender newSender = nativeAddTrack(track.nativeTrack, streamIds);
900 if (newSender == null) {
901 throw new IllegalStateException("C++ addTrack failed.");
902 }
903 senders.add(newSender);
904 return newSender;
905 }
906
907 /**
908 * Stops sending media from sender. The sender will still appear in getSenders. Future
909 * calls to createOffer will mark the m section for the corresponding transceiver as
910 * receive only or inactive, as defined in JSEP. Returns true on success.
911 */
912 public boolean removeTrack(RtpSender sender) {
913 if (sender == null) {
914 throw new NullPointerException("No RtpSender specified for removeTrack.");
915 }
916 return nativeRemoveTrack(sender.nativeRtpSender);
917 }
918
919 /**
920 * Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a
921 * transceiver will cause future calls to CreateOffer to add a media description
922 * for the corresponding transceiver.
923 *
924 * <p>The initial value of |mid| in the returned transceiver is null. Setting a
925 * new session description may change it to a non-null value.
926 *
927 * <p>https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
928 *
929 * <p>If a MediaStreamTrack is specified then a transceiver will be added with a
930 * sender set to transmit the given track. The kind
931 * of the transceiver (and sender/receiver) will be derived from the kind of
932 * the track.
933 *
934 * <p>If MediaType is specified then a transceiver will be added based upon that type.
935 * This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO.
936 *
937 * <p>Optionally, an RtpTransceiverInit structure can be specified to configure
938 * the transceiver from construction. If not specified, the transceiver will
939 * default to having a direction of kSendRecv and not be part of any streams.
940 *
941 * <p>Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified.
942 * @throws IllegalStateException if an error accors in C++ addTransceiver
943 */
944 public RtpTransceiver addTransceiver(MediaStreamTrack track) {
945 return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit());
946 }
947
948 public RtpTransceiver addTransceiver(
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100949 MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init) {
Seth Hampsonc384e142018-03-06 15:47:10 -0800950 if (track == null) {
951 throw new NullPointerException("No MediaStreamTrack specified for addTransceiver.");
952 }
953 if (init == null) {
954 init = new RtpTransceiver.RtpTransceiverInit();
955 }
956 RtpTransceiver newTransceiver = nativeAddTransceiverWithTrack(track.nativeTrack, init);
957 if (newTransceiver == null) {
958 throw new IllegalStateException("C++ addTransceiver failed.");
959 }
960 transceivers.add(newTransceiver);
961 return newTransceiver;
962 }
963
964 public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) {
965 return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit());
966 }
967
968 public RtpTransceiver addTransceiver(
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100969 MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init) {
Seth Hampsonc384e142018-03-06 15:47:10 -0800970 if (mediaType == null) {
971 throw new NullPointerException("No MediaType specified for addTransceiver.");
972 }
973 if (init == null) {
974 init = new RtpTransceiver.RtpTransceiverInit();
975 }
976 RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init);
977 if (newTransceiver == null) {
978 throw new IllegalStateException("C++ addTransceiver failed.");
979 }
980 transceivers.add(newTransceiver);
981 return newTransceiver;
982 }
983
deadbeef82215872017-04-18 10:27:51 -0700984 // Older, non-standard implementation of getStats.
985 @Deprecated
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100986 public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100987 return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
deadbeef82215872017-04-18 10:27:51 -0700988 }
989
Seth Hampsonc384e142018-03-06 15:47:10 -0800990 /**
991 * Gets stats using the new stats collection API, see webrtc/api/stats/. These
992 * will replace old stats collection API when the new API has matured enough.
993 */
deadbeef82215872017-04-18 10:27:51 -0700994 public void getStats(RTCStatsCollectorCallback callback) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100995 nativeNewGetStats(callback);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996 }
997
Seth Hampsonc384e142018-03-06 15:47:10 -0800998 /**
999 * Limits the bandwidth allocated for all RTP streams sent by this
1000 * PeerConnection. Pass null to leave a value unchanged.
1001 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001002 public boolean setBitrate(Integer min, Integer current, Integer max) {
1003 return nativeSetBitrate(min, current, max);
1004 }
zsteind89b0bc2017-08-03 11:11:40 -07001005
Seth Hampsonc384e142018-03-06 15:47:10 -08001006 /**
1007 * Starts recording an RTC event log.
1008 *
1009 * Ownership of the file is transfered to the native code. If an RTC event
1010 * log is already being recorded, it will be stopped and a new one will start
1011 * using the provided file. Logging will continue until the stopRtcEventLog
1012 * function is called. The max_size_bytes argument is ignored, it is added
1013 * for future use.
1014 */
ivoc0c6f0f62016-07-06 04:34:23 -07001015 public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001016 return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
ivoc14d5dbe2016-07-04 07:06:55 -07001017 }
1018
Seth Hampsonc384e142018-03-06 15:47:10 -08001019 /**
1020 * Stops recording an RTC event log. If no RTC event log is currently being
1021 * recorded, this call will have no effect.
1022 */
ivoc14d5dbe2016-07-04 07:06:55 -07001023 public void stopRtcEventLog() {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001024 nativeStopRtcEventLog();
ivoc14d5dbe2016-07-04 07:06:55 -07001025 }
1026
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001027 // TODO(fischman): add support for DTMF-related methods once that API
1028 // stabilizes.
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001029 public SignalingState signalingState() {
1030 return nativeSignalingState();
1031 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001032
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001033 public IceConnectionState iceConnectionState() {
1034 return nativeIceConnectionState();
1035 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001036
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001037 public IceGatheringState iceGatheringState() {
1038 return nativeIceGatheringState();
1039 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001040
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001041 public void close() {
1042 nativeClose();
1043 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044
deadbeef43697f62017-09-12 10:52:14 -07001045 /**
1046 * Free native resources associated with this PeerConnection instance.
Seth Hampsonc384e142018-03-06 15:47:10 -08001047 *
deadbeef43697f62017-09-12 10:52:14 -07001048 * This method removes a reference count from the C++ PeerConnection object,
1049 * which should result in it being destroyed. It also calls equivalent
1050 * "dispose" methods on the Java objects attached to this PeerConnection
1051 * (streams, senders, receivers), such that their associated C++ objects
1052 * will also be destroyed.
Seth Hampsonc384e142018-03-06 15:47:10 -08001053 *
1054 * <p>Note that this method cannot be safely called from an observer callback
deadbeef43697f62017-09-12 10:52:14 -07001055 * (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for
1056 * example, destroy the PeerConnection after an "ICE failed" callback, you
1057 * must do this asynchronously (in other words, unwind the stack first). See
1058 * <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=3721">bug
1059 * 3721</a> for more details.
1060 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061 public void dispose() {
1062 close();
1063 for (MediaStream stream : localStreams) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001064 nativeRemoveLocalStream(stream.nativeStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001065 stream.dispose();
1066 }
1067 localStreams.clear();
deadbeef4139c0f2015-10-06 12:29:25 -07001068 for (RtpSender sender : senders) {
1069 sender.dispose();
1070 }
1071 senders.clear();
1072 for (RtpReceiver receiver : receivers) {
1073 receiver.dispose();
1074 }
Seth Hampsonc384e142018-03-06 15:47:10 -08001075 for (RtpTransceiver transceiver : transceivers) {
1076 transceiver.dispose();
1077 }
1078 transceivers.clear();
deadbeef4139c0f2015-10-06 12:29:25 -07001079 receivers.clear();
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001080 nativeFreeOwnedPeerConnection(nativePeerConnection);
1081 }
1082
1083 /** Returns a pointer to the native webrtc::PeerConnectionInterface. */
1084 public long getNativePeerConnection() {
1085 return nativeGetNativePeerConnection();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001086 }
1087
Magnus Jedvert9060eb12017-12-12 12:52:54 +01001088 @CalledByNative
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001089 long getNativeOwnedPeerConnection() {
Magnus Jedvert9060eb12017-12-12 12:52:54 +01001090 return nativePeerConnection;
1091 }
1092
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001093 public static long createNativePeerConnectionObserver(Observer observer) {
1094 return nativeCreatePeerConnectionObserver(observer);
1095 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001096
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001097 private native long nativeGetNativePeerConnection();
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001098 private native SessionDescription nativeGetLocalDescription();
1099 private native SessionDescription nativeGetRemoteDescription();
1100 private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init);
1101 private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints);
1102 private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints);
1103 private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp);
1104 private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp);
1105 private native void nativeSetAudioPlayout(boolean playout);
1106 private native void nativeSetAudioRecording(boolean recording);
1107 private native boolean nativeSetBitrate(Integer min, Integer current, Integer max);
1108 private native SignalingState nativeSignalingState();
1109 private native IceConnectionState nativeIceConnectionState();
1110 private native IceGatheringState nativeIceGatheringState();
1111 private native void nativeClose();
1112 private static native long nativeCreatePeerConnectionObserver(Observer observer);
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001113 private static native void nativeFreeOwnedPeerConnection(long ownedPeerConnection);
1114 private native boolean nativeSetConfiguration(RTCConfiguration config);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001115 private native boolean nativeAddIceCandidate(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001116 String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001117 private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
1118 private native boolean nativeAddLocalStream(long stream);
1119 private native void nativeRemoveLocalStream(long stream);
1120 private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
1121 private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
1122 private native RtpSender nativeCreateSender(String kind, String stream_id);
1123 private native List<RtpSender> nativeGetSenders();
1124 private native List<RtpReceiver> nativeGetReceivers();
Seth Hampsonc384e142018-03-06 15:47:10 -08001125 private native List<RtpTransceiver> nativeGetTransceivers();
1126 private native RtpSender nativeAddTrack(long track, List<String> streamIds);
1127 private native boolean nativeRemoveTrack(long sender);
1128 private native RtpTransceiver nativeAddTransceiverWithTrack(
1129 long track, RtpTransceiver.RtpTransceiverInit init);
1130 private native RtpTransceiver nativeAddTransceiverOfType(
1131 MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001132 private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
1133 private native void nativeStopRtcEventLog();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001134}