blob: 0dc5c6344136cc282d3ea773d24ce931673e09f4 [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
Artem Titarenko69540f42018-12-10 12:30:46 +010013import android.support.annotation.Nullable;
Magnus Jedvert6062f372017-11-16 16:53:12 +010014import java.util.ArrayList;
Qingsi Wanga0d45802019-01-15 13:33:11 -080015import java.util.Arrays;
Sami Kalliomäki3e189a62017-11-24 11:13:39 +010016import java.util.Collections;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017import java.util.List;
Patrik Höglundbd6ffaf2018-11-16 14:55:16 +010018import org.webrtc.DataChannel;
19import org.webrtc.MediaStreamTrack;
20import org.webrtc.RtpTransceiver;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000021
22/**
23 * Java-land version of the PeerConnection APIs; wraps the C++ API
24 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the
25 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
26 * http://www.w3.org/TR/mediacapture-streams/
27 */
28public class PeerConnection {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000029 /** Tracks PeerConnectionInterface::IceGatheringState */
Magnus Jedvertba700f62017-12-04 13:43:27 +010030 public enum IceGatheringState {
31 NEW,
32 GATHERING,
33 COMPLETE;
34
35 @CalledByNative("IceGatheringState")
36 static IceGatheringState fromNativeIndex(int nativeIndex) {
37 return values()[nativeIndex];
38 }
39 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
41 /** Tracks PeerConnectionInterface::IceConnectionState */
42 public enum IceConnectionState {
sakalb6760f92016-09-29 04:12:44 -070043 NEW,
44 CHECKING,
45 CONNECTED,
46 COMPLETED,
47 FAILED,
48 DISCONNECTED,
Magnus Jedvertba700f62017-12-04 13:43:27 +010049 CLOSED;
50
51 @CalledByNative("IceConnectionState")
52 static IceConnectionState fromNativeIndex(int nativeIndex) {
53 return values()[nativeIndex];
54 }
sakalb6760f92016-09-29 04:12:44 -070055 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056
Jonas Olssonf01d8c82018-11-08 15:19:04 +010057 /** Tracks PeerConnectionInterface::PeerConnectionState */
58 public enum PeerConnectionState {
59 NEW,
60 CONNECTING,
61 CONNECTED,
62 DISCONNECTED,
63 FAILED,
64 CLOSED;
65
66 @CalledByNative("PeerConnectionState")
67 static PeerConnectionState fromNativeIndex(int nativeIndex) {
68 return values()[nativeIndex];
69 }
70 }
71
hnsl04833622017-01-09 08:35:45 -080072 /** Tracks PeerConnectionInterface::TlsCertPolicy */
73 public enum TlsCertPolicy {
74 TLS_CERT_POLICY_SECURE,
75 TLS_CERT_POLICY_INSECURE_NO_CHECK,
76 }
77
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078 /** Tracks PeerConnectionInterface::SignalingState */
79 public enum SignalingState {
sakalb6760f92016-09-29 04:12:44 -070080 STABLE,
81 HAVE_LOCAL_OFFER,
82 HAVE_LOCAL_PRANSWER,
83 HAVE_REMOTE_OFFER,
84 HAVE_REMOTE_PRANSWER,
Magnus Jedvertba700f62017-12-04 13:43:27 +010085 CLOSED;
86
87 @CalledByNative("SignalingState")
88 static SignalingState fromNativeIndex(int nativeIndex) {
89 return values()[nativeIndex];
90 }
sakalb6760f92016-09-29 04:12:44 -070091 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092
93 /** Java version of PeerConnectionObserver. */
94 public static interface Observer {
95 /** Triggered when the SignalingState changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010096 @CalledByNative("Observer") void onSignalingChange(SignalingState newState);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097
98 /** Triggered when the IceConnectionState changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +010099 @CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100
Jonas Olssonf01d8c82018-11-08 15:19:04 +0100101 /** Triggered when the PeerConnectionState changes. */
102 @CalledByNative("Observer")
103 default void onConnectionChange(PeerConnectionState newState) {}
104
Peter Thatcher54360512015-07-08 11:08:35 -0700105 /** Triggered when the ICE connection receiving status changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100106 @CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving);
Peter Thatcher54360512015-07-08 11:08:35 -0700107
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000108 /** Triggered when the IceGatheringState changes. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100109 @CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110
111 /** Triggered when a new ICE candidate has been found. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100112 @CalledByNative("Observer") void onIceCandidate(IceCandidate candidate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000113
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700114 /** Triggered when some ICE candidates have been removed. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100115 @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700116
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117 /** Triggered when media is received on a new stream from remote peer. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100118 @CalledByNative("Observer") void onAddStream(MediaStream stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119
120 /** Triggered when a remote peer close a stream. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100121 @CalledByNative("Observer") void onRemoveStream(MediaStream stream);
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000122
123 /** Triggered when a remote peer opens a DataChannel. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100124 @CalledByNative("Observer") void onDataChannel(DataChannel dataChannel);
fischman@webrtc.orgd7568a02014-01-13 22:04:12 +0000125
126 /** Triggered when renegotiation is necessary. */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100127 @CalledByNative("Observer") void onRenegotiationNeeded();
zhihuangdcccda72016-12-21 14:08:03 -0800128
129 /**
130 * Triggered when a new track is signaled by the remote peer, as a result of
131 * setRemoteDescription.
132 */
Magnus Jedvertba700f62017-12-04 13:43:27 +0100133 @CalledByNative("Observer") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams);
Seth Hampson31dbc242018-05-07 09:28:19 -0700134
135 /**
136 * Triggered when the signaling from SetRemoteDescription indicates that a transceiver
137 * will be receiving media from a remote endpoint. This is only called if UNIFIED_PLAN
138 * semantics are specified. The transceiver will be disposed automatically.
139 */
140 @CalledByNative("Observer") default void onTrack(RtpTransceiver transceiver){};
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000141 }
142
143 /** Java version of PeerConnectionInterface.IceServer. */
144 public static class IceServer {
Emad Omaradab1d2d2017-06-16 15:43:11 -0700145 // List of URIs associated with this server. Valid formats are described
146 // in RFC7064 and RFC7065, and more may be added in the future. The "host"
147 // part of the URI may contain either an IP address or a hostname.
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700148 @Deprecated public final String uri;
149 public final List<String> urls;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150 public final String username;
151 public final String password;
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000152 public final TlsCertPolicy tlsCertPolicy;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153
Emad Omaradab1d2d2017-06-16 15:43:11 -0700154 // If the URIs in |urls| only contain IP addresses, this field can be used
155 // to indicate the hostname, which may be necessary for TLS (using the SNI
156 // extension). If |urls| itself contains the hostname, this isn't
157 // necessary.
158 public final String hostname;
159
Diogo Real1dca9d52017-08-29 12:18:32 -0700160 // List of protocols to be used in the TLS ALPN extension.
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000161 public final List<String> tlsAlpnProtocols;
Diogo Real1dca9d52017-08-29 12:18:32 -0700162
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700163 // List of elliptic curves to be used in the TLS elliptic curves extension.
164 // Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000165 public final List<String> tlsEllipticCurves;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700166
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 /** Convenience constructor for STUN servers. */
Diogo Real05ea2b32017-08-31 00:12:58 -0700168 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169 public IceServer(String uri) {
170 this(uri, "", "");
171 }
172
Diogo Real05ea2b32017-08-31 00:12:58 -0700173 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 public IceServer(String uri, String username, String password) {
hnsl04833622017-01-09 08:35:45 -0800175 this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE);
176 }
177
Diogo Real05ea2b32017-08-31 00:12:58 -0700178 @Deprecated
hnsl04833622017-01-09 08:35:45 -0800179 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) {
Emad Omaradab1d2d2017-06-16 15:43:11 -0700180 this(uri, username, password, tlsCertPolicy, "");
181 }
182
Diogo Real05ea2b32017-08-31 00:12:58 -0700183 @Deprecated
Emad Omaradab1d2d2017-06-16 15:43:11 -0700184 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
185 String hostname) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700186 this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null,
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000187 null);
Diogo Real1dca9d52017-08-29 12:18:32 -0700188 }
189
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700190 private IceServer(String uri, List<String> urls, String username, String password,
191 TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols,
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000192 List<String> tlsEllipticCurves) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700193 if (uri == null || urls == null || urls.isEmpty()) {
194 throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()");
195 }
196 for (String it : urls) {
197 if (it == null) {
198 throw new IllegalArgumentException("urls element is null: " + urls);
199 }
200 }
201 if (username == null) {
202 throw new IllegalArgumentException("username == null");
203 }
204 if (password == null) {
205 throw new IllegalArgumentException("password == null");
206 }
207 if (hostname == null) {
208 throw new IllegalArgumentException("hostname == null");
209 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 this.uri = uri;
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700211 this.urls = urls;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 this.username = username;
213 this.password = password;
hnsl04833622017-01-09 08:35:45 -0800214 this.tlsCertPolicy = tlsCertPolicy;
Emad Omaradab1d2d2017-06-16 15:43:11 -0700215 this.hostname = hostname;
Diogo Real1dca9d52017-08-29 12:18:32 -0700216 this.tlsAlpnProtocols = tlsAlpnProtocols;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700217 this.tlsEllipticCurves = tlsEllipticCurves;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 }
219
Sami Kalliomäkibde473e2017-10-30 13:34:41 +0100220 @Override
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221 public String toString() {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700222 return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000223 + "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
Diogo Real1dca9d52017-08-29 12:18:32 -0700224 }
225
Qingsi Wanga0d45802019-01-15 13:33:11 -0800226 @Override
227 public boolean equals(@Nullable Object obj) {
228 if (obj == null) {
229 return false;
230 }
231 if (obj == this) {
232 return true;
233 }
234 if (!(obj instanceof IceServer)) {
235 return false;
236 }
237 IceServer other = (IceServer) obj;
238 return (uri.equals(other.uri) && urls.equals(other.urls) && username.equals(other.username)
239 && password.equals(other.password) && tlsCertPolicy.equals(other.tlsCertPolicy)
240 && hostname.equals(other.hostname) && tlsAlpnProtocols.equals(other.tlsAlpnProtocols)
241 && tlsEllipticCurves.equals(other.tlsEllipticCurves));
242 }
243
244 @Override
245 public int hashCode() {
246 Object[] values = {uri, urls, username, password, tlsCertPolicy, hostname, tlsAlpnProtocols,
247 tlsEllipticCurves};
248 return Arrays.hashCode(values);
249 }
250
Diogo Real1dca9d52017-08-29 12:18:32 -0700251 public static Builder builder(String uri) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700252 return new Builder(Collections.singletonList(uri));
253 }
254
255 public static Builder builder(List<String> urls) {
256 return new Builder(urls);
Diogo Real1dca9d52017-08-29 12:18:32 -0700257 }
258
259 public static class Builder {
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100260 @Nullable private final List<String> urls;
Diogo Real1dca9d52017-08-29 12:18:32 -0700261 private String username = "";
262 private String password = "";
263 private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
264 private String hostname = "";
265 private List<String> tlsAlpnProtocols;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700266 private List<String> tlsEllipticCurves;
Diogo Real1dca9d52017-08-29 12:18:32 -0700267
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700268 private Builder(List<String> urls) {
269 if (urls == null || urls.isEmpty()) {
270 throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls);
271 }
272 this.urls = urls;
Diogo Real1dca9d52017-08-29 12:18:32 -0700273 }
274
275 public Builder setUsername(String username) {
276 this.username = username;
277 return this;
278 }
279
280 public Builder setPassword(String password) {
281 this.password = password;
282 return this;
283 }
284
285 public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) {
286 this.tlsCertPolicy = tlsCertPolicy;
287 return this;
288 }
289
290 public Builder setHostname(String hostname) {
291 this.hostname = hostname;
292 return this;
293 }
294
295 public Builder setTlsAlpnProtocols(List<String> tlsAlpnProtocols) {
296 this.tlsAlpnProtocols = tlsAlpnProtocols;
297 return this;
298 }
299
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700300 public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
301 this.tlsEllipticCurves = tlsEllipticCurves;
302 return this;
303 }
304
Diogo Real1dca9d52017-08-29 12:18:32 -0700305 public IceServer createIceServer() {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700306 return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname,
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000307 tlsAlpnProtocols, tlsEllipticCurves);
Diogo Real1dca9d52017-08-29 12:18:32 -0700308 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309 }
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100310
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100311 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100312 @CalledByNative("IceServer")
313 List<String> getUrls() {
314 return urls;
315 }
316
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100317 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100318 @CalledByNative("IceServer")
319 String getUsername() {
320 return username;
321 }
322
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100323 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100324 @CalledByNative("IceServer")
325 String getPassword() {
326 return password;
327 }
328
329 @CalledByNative("IceServer")
330 TlsCertPolicy getTlsCertPolicy() {
331 return tlsCertPolicy;
332 }
333
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100334 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100335 @CalledByNative("IceServer")
336 String getHostname() {
337 return hostname;
338 }
339
340 @CalledByNative("IceServer")
341 List<String> getTlsAlpnProtocols() {
342 return tlsAlpnProtocols;
343 }
344
345 @CalledByNative("IceServer")
346 List<String> getTlsEllipticCurves() {
347 return tlsEllipticCurves;
348 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 }
350
Jiayang Liucac1b382015-04-30 12:35:24 -0700351 /** Java version of PeerConnectionInterface.IceTransportsType */
sakalb6760f92016-09-29 04:12:44 -0700352 public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }
Jiayang Liucac1b382015-04-30 12:35:24 -0700353
354 /** Java version of PeerConnectionInterface.BundlePolicy */
sakalb6760f92016-09-29 04:12:44 -0700355 public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }
Jiayang Liucac1b382015-04-30 12:35:24 -0700356
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700357 /** Java version of PeerConnectionInterface.RtcpMuxPolicy */
sakalb6760f92016-09-29 04:12:44 -0700358 public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }
glaznev97579a42015-09-01 11:31:27 -0700359
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700360 /** Java version of PeerConnectionInterface.TcpCandidatePolicy */
sakalb6760f92016-09-29 04:12:44 -0700361 public enum TcpCandidatePolicy { ENABLED, DISABLED }
Jiayang Liucac1b382015-04-30 12:35:24 -0700362
honghaiz60347052016-05-31 18:29:12 -0700363 /** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
sakalb6760f92016-09-29 04:12:44 -0700364 public enum CandidateNetworkPolicy { ALL, LOW_COST }
honghaiz60347052016-05-31 18:29:12 -0700365
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800366 // Keep in sync with webrtc/rtc_base/network_constants.h.
367 public enum AdapterType {
368 UNKNOWN,
369 ETHERNET,
370 WIFI,
371 CELLULAR,
372 VPN,
373 LOOPBACK,
374 }
375
glaznev97579a42015-09-01 11:31:27 -0700376 /** Java version of rtc::KeyType */
sakalb6760f92016-09-29 04:12:44 -0700377 public enum KeyType { RSA, ECDSA }
glaznev97579a42015-09-01 11:31:27 -0700378
honghaiz1f429e32015-09-28 07:57:34 -0700379 /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
sakalb6760f92016-09-29 04:12:44 -0700380 public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }
honghaiz1f429e32015-09-28 07:57:34 -0700381
Steve Antond960a0c2017-07-17 12:33:07 -0700382 /** Java version of rtc::IntervalRange */
383 public static class IntervalRange {
384 private final int min;
385 private final int max;
386
387 public IntervalRange(int min, int max) {
388 this.min = min;
389 this.max = max;
390 }
391
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100392 @CalledByNative("IntervalRange")
Steve Antond960a0c2017-07-17 12:33:07 -0700393 public int getMin() {
394 return min;
395 }
396
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100397 @CalledByNative("IntervalRange")
Steve Antond960a0c2017-07-17 12:33:07 -0700398 public int getMax() {
399 return max;
400 }
401 }
402
Seth Hampsonc384e142018-03-06 15:47:10 -0800403 /**
404 * Java version of webrtc::SdpSemantics.
405 *
406 * Configure the SDP semantics used by this PeerConnection. Note that the
407 * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The
408 * RtpTransceiver API is only available with UNIFIED_PLAN semantics.
409 *
410 * <p>PLAN_B will cause PeerConnection to create offers and answers with at
411 * most one audio and one video m= section with multiple RtpSenders and
412 * RtpReceivers specified as multiple a=ssrc lines within the section. This
413 * will also cause PeerConnection to ignore all but the first m= section of
414 * the same media type.
415 *
416 * <p>UNIFIED_PLAN will cause PeerConnection to create offers and answers with
417 * multiple m= sections where each m= section maps to one RtpSender and one
418 * RtpReceiver (an RtpTransceiver), either both audio or both video. This
419 * will also cause PeerConnection to ignore all but the first a=ssrc lines
420 * that form a Plan B stream.
421 *
422 * <p>For users who wish to send multiple audio/video streams and need to stay
423 * interoperable with legacy WebRTC implementations, specify PLAN_B.
424 *
425 * <p>For users who wish to send multiple audio/video streams and/or wish to
426 * use the new RtpTransceiver API, specify UNIFIED_PLAN.
427 */
428 public enum SdpSemantics { PLAN_B, UNIFIED_PLAN }
429
Jiayang Liucac1b382015-04-30 12:35:24 -0700430 /** Java version of PeerConnectionInterface.RTCConfiguration */
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800431 // TODO(qingsi): Resolve the naming inconsistency of fields with/without units.
Jiayang Liucac1b382015-04-30 12:35:24 -0700432 public static class RTCConfiguration {
433 public IceTransportsType iceTransportsType;
434 public List<IceServer> iceServers;
435 public BundlePolicy bundlePolicy;
Michael Iedema02137862018-10-09 15:30:01 +0200436 @Nullable public RtcCertificatePem certificate;
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700437 public RtcpMuxPolicy rtcpMuxPolicy;
Jiayang Liucac1b382015-04-30 12:35:24 -0700438 public TcpCandidatePolicy tcpCandidatePolicy;
honghaiz60347052016-05-31 18:29:12 -0700439 public CandidateNetworkPolicy candidateNetworkPolicy;
Henrik Lundin64dad832015-05-11 12:44:23 +0200440 public int audioJitterBufferMaxPackets;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200441 public boolean audioJitterBufferFastAccelerate;
honghaiz4edc39c2015-09-01 09:53:56 -0700442 public int iceConnectionReceivingTimeout;
Honghai Zhang381b4212015-12-04 12:24:03 -0800443 public int iceBackupCandidatePairPingInterval;
glaznev97579a42015-09-01 11:31:27 -0700444 public KeyType keyType;
honghaiz1f429e32015-09-28 07:57:34 -0700445 public ContinualGatheringPolicy continualGatheringPolicy;
deadbeefbe0c96f2016-05-18 16:20:14 -0700446 public int iceCandidatePoolSize;
Honghai Zhangd78ecf72016-07-01 14:40:40 -0700447 public boolean pruneTurnPorts;
Taylor Brandstettere9851112016-07-01 11:11:13 -0700448 public boolean presumeWritableWhenFullyRelayed;
Qingsi Wange6826d22018-03-08 14:55:14 -0800449 // The following fields define intervals in milliseconds at which ICE
450 // connectivity checks are sent.
451 //
452 // We consider ICE is "strongly connected" for an agent when there is at
453 // least one candidate pair that currently succeeds in connectivity check
454 // from its direction i.e. sending a ping and receives a ping response, AND
455 // all candidate pairs have sent a minimum number of pings for connectivity
456 // (this number is implementation-specific). Otherwise, ICE is considered in
457 // "weak connectivity".
458 //
459 // Note that the above notion of strong and weak connectivity is not defined
460 // in RFC 5245, and they apply to our current ICE implementation only.
461 //
462 // 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to
463 // ALL candidate pairs when ICE is strongly connected,
464 // 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL
465 // pairs when ICE is weakly connected, and
466 // 3) iceCheckMinInterval defines the minimal interval (equivalently the
467 // maximum rate) that overrides the above two intervals when either of them
468 // is less.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100469 @Nullable public Integer iceCheckIntervalStrongConnectivityMs;
470 @Nullable public Integer iceCheckIntervalWeakConnectivityMs;
471 @Nullable public Integer iceCheckMinInterval;
Qingsi Wang22e623a2018-03-13 10:53:57 -0700472 // The time period in milliseconds for which a candidate pair must wait for response to
473 // connectivitiy checks before it becomes unwritable.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100474 @Nullable public Integer iceUnwritableTimeMs;
Qingsi Wang22e623a2018-03-13 10:53:57 -0700475 // The minimum number of connectivity checks that a candidate pair must sent without receiving
476 // response before it becomes unwritable.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100477 @Nullable public Integer iceUnwritableMinChecks;
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800478 // The interval in milliseconds at which STUN candidates will resend STUN binding requests
479 // to keep NAT bindings open.
480 // The default value in the implementation is used if this field is null.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100481 @Nullable public Integer stunCandidateKeepaliveIntervalMs;
zhihuangb09b3f92017-03-07 14:40:51 -0800482 public boolean disableIPv6OnWifi;
deadbeef28e29192017-07-27 09:14:38 -0700483 // By default, PeerConnection will use a limited number of IPv6 network
484 // interfaces, in order to avoid too many ICE candidate pairs being created
485 // and delaying ICE completion.
486 //
487 // Can be set to Integer.MAX_VALUE to effectively disable the limit.
488 public int maxIPv6Networks;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100489 @Nullable public IntervalRange iceRegatherIntervalRange;
Jiayang Liucac1b382015-04-30 12:35:24 -0700490
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100491 // These values will be overridden by MediaStream constraints if deprecated constraints-based
492 // create peerconnection interface is used.
493 public boolean disableIpv6;
494 public boolean enableDscp;
495 public boolean enableCpuOveruseDetection;
496 public boolean enableRtpDataChannel;
497 public boolean suspendBelowMinBitrate;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100498 @Nullable public Integer screencastMinBitrate;
499 @Nullable public Boolean combinedAudioVideoBwe;
500 @Nullable public Boolean enableDtlsSrtp;
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800501 // Use "Unknown" to represent no preference of adapter types, not the
502 // preference of adapters of unknown types.
503 public AdapterType networkPreference;
Seth Hampsonc384e142018-03-06 15:47:10 -0800504 public SdpSemantics sdpSemantics;
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100505
Jonas Orelandbdcee282017-10-10 14:01:40 +0200506 // This is an optional wrapper for the C++ webrtc::TurnCustomizer.
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100507 @Nullable public TurnCustomizer turnCustomizer;
Jonas Orelandbdcee282017-10-10 14:01:40 +0200508
Zhi Huangb57e1692018-06-12 11:41:11 -0700509 // Actively reset the SRTP parameters whenever the DTLS transports underneath are reset for
510 // every offer/answer negotiation.This is only intended to be a workaround for crbug.com/835958
511 public boolean activeResetSrtpParams;
512
Piotr (Peter) Slatala09beff22018-10-17 07:22:40 -0700513 /*
514 * Experimental flag that enables a use of media transport. If this is true, the media transport
515 * factory MUST be provided to the PeerConnectionFactory.
516 */
517 public boolean useMediaTransport;
518
Bjorn Mellema9bbd862018-11-02 09:07:48 -0700519 /*
520 * Experimental flag that enables a use of media transport for data channels. If this is true,
521 * the media transport factory MUST be provided to the PeerConnectionFactory.
522 */
523 public boolean useMediaTransportForDataChannels;
524
Benjamin Wright8c27cca2018-10-25 10:16:44 -0700525 /**
526 * Defines advanced optional cryptographic settings related to SRTP and
527 * frame encryption for native WebRTC. Setting this will overwrite any
528 * options set through the PeerConnectionFactory (which is deprecated).
529 */
530 @Nullable public CryptoOptions cryptoOptions;
531
deadbeef28e29192017-07-27 09:14:38 -0700532 // TODO(deadbeef): Instead of duplicating the defaults here, we should do
533 // something to pick up the defaults from C++. The Objective-C equivalent
534 // of RTCConfiguration does that.
Jiayang Liucac1b382015-04-30 12:35:24 -0700535 public RTCConfiguration(List<IceServer> iceServers) {
536 iceTransportsType = IceTransportsType.ALL;
537 bundlePolicy = BundlePolicy.BALANCED;
zhihuang4dfb8ce2016-11-23 10:30:12 -0800538 rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE;
Jiayang Liucac1b382015-04-30 12:35:24 -0700539 tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
Sami Kalliomäki9828beb2017-10-26 16:21:22 +0200540 candidateNetworkPolicy = CandidateNetworkPolicy.ALL;
Jiayang Liucac1b382015-04-30 12:35:24 -0700541 this.iceServers = iceServers;
Henrik Lundin64dad832015-05-11 12:44:23 +0200542 audioJitterBufferMaxPackets = 50;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200543 audioJitterBufferFastAccelerate = false;
honghaiz4edc39c2015-09-01 09:53:56 -0700544 iceConnectionReceivingTimeout = -1;
Honghai Zhang381b4212015-12-04 12:24:03 -0800545 iceBackupCandidatePairPingInterval = -1;
glaznev97579a42015-09-01 11:31:27 -0700546 keyType = KeyType.ECDSA;
honghaiz1f429e32015-09-28 07:57:34 -0700547 continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE;
deadbeefbe0c96f2016-05-18 16:20:14 -0700548 iceCandidatePoolSize = 0;
Honghai Zhangd78ecf72016-07-01 14:40:40 -0700549 pruneTurnPorts = false;
Taylor Brandstettere9851112016-07-01 11:11:13 -0700550 presumeWritableWhenFullyRelayed = false;
Qingsi Wange6826d22018-03-08 14:55:14 -0800551 iceCheckIntervalStrongConnectivityMs = null;
552 iceCheckIntervalWeakConnectivityMs = null;
skvlad51072462017-02-02 11:50:14 -0800553 iceCheckMinInterval = null;
Qingsi Wang22e623a2018-03-13 10:53:57 -0700554 iceUnwritableTimeMs = null;
555 iceUnwritableMinChecks = null;
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800556 stunCandidateKeepaliveIntervalMs = null;
zhihuangb09b3f92017-03-07 14:40:51 -0800557 disableIPv6OnWifi = false;
deadbeef28e29192017-07-27 09:14:38 -0700558 maxIPv6Networks = 5;
Steve Antond960a0c2017-07-17 12:33:07 -0700559 iceRegatherIntervalRange = null;
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100560 disableIpv6 = false;
561 enableDscp = false;
562 enableCpuOveruseDetection = true;
563 enableRtpDataChannel = false;
564 suspendBelowMinBitrate = false;
565 screencastMinBitrate = null;
566 combinedAudioVideoBwe = null;
567 enableDtlsSrtp = null;
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800568 networkPreference = AdapterType.UNKNOWN;
Seth Hampsonc384e142018-03-06 15:47:10 -0800569 sdpSemantics = SdpSemantics.PLAN_B;
Zhi Huangb57e1692018-06-12 11:41:11 -0700570 activeResetSrtpParams = false;
Piotr (Peter) Slatala09beff22018-10-17 07:22:40 -0700571 useMediaTransport = false;
Bjorn Mellema9bbd862018-11-02 09:07:48 -0700572 useMediaTransportForDataChannels = false;
Benjamin Wright8c27cca2018-10-25 10:16:44 -0700573 cryptoOptions = null;
Jiayang Liucac1b382015-04-30 12:35:24 -0700574 }
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100575
576 @CalledByNative("RTCConfiguration")
577 IceTransportsType getIceTransportsType() {
578 return iceTransportsType;
579 }
580
581 @CalledByNative("RTCConfiguration")
582 List<IceServer> getIceServers() {
583 return iceServers;
584 }
585
586 @CalledByNative("RTCConfiguration")
587 BundlePolicy getBundlePolicy() {
588 return bundlePolicy;
589 }
590
Michael Iedema02137862018-10-09 15:30:01 +0200591 @Nullable
592 @CalledByNative("RTCConfiguration")
593 RtcCertificatePem getCertificate() {
594 return certificate;
595 }
596
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100597 @CalledByNative("RTCConfiguration")
598 RtcpMuxPolicy getRtcpMuxPolicy() {
599 return rtcpMuxPolicy;
600 }
601
602 @CalledByNative("RTCConfiguration")
603 TcpCandidatePolicy getTcpCandidatePolicy() {
604 return tcpCandidatePolicy;
605 }
606
607 @CalledByNative("RTCConfiguration")
608 CandidateNetworkPolicy getCandidateNetworkPolicy() {
609 return candidateNetworkPolicy;
610 }
611
612 @CalledByNative("RTCConfiguration")
613 int getAudioJitterBufferMaxPackets() {
614 return audioJitterBufferMaxPackets;
615 }
616
617 @CalledByNative("RTCConfiguration")
618 boolean getAudioJitterBufferFastAccelerate() {
619 return audioJitterBufferFastAccelerate;
620 }
621
622 @CalledByNative("RTCConfiguration")
623 int getIceConnectionReceivingTimeout() {
624 return iceConnectionReceivingTimeout;
625 }
626
627 @CalledByNative("RTCConfiguration")
628 int getIceBackupCandidatePairPingInterval() {
629 return iceBackupCandidatePairPingInterval;
630 }
631
632 @CalledByNative("RTCConfiguration")
633 KeyType getKeyType() {
634 return keyType;
635 }
636
637 @CalledByNative("RTCConfiguration")
638 ContinualGatheringPolicy getContinualGatheringPolicy() {
639 return continualGatheringPolicy;
640 }
641
642 @CalledByNative("RTCConfiguration")
643 int getIceCandidatePoolSize() {
644 return iceCandidatePoolSize;
645 }
646
647 @CalledByNative("RTCConfiguration")
648 boolean getPruneTurnPorts() {
649 return pruneTurnPorts;
650 }
651
652 @CalledByNative("RTCConfiguration")
653 boolean getPresumeWritableWhenFullyRelayed() {
654 return presumeWritableWhenFullyRelayed;
655 }
656
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100657 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100658 @CalledByNative("RTCConfiguration")
Qingsi Wange6826d22018-03-08 14:55:14 -0800659 Integer getIceCheckIntervalStrongConnectivity() {
660 return iceCheckIntervalStrongConnectivityMs;
661 }
662
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100663 @Nullable
Qingsi Wange6826d22018-03-08 14:55:14 -0800664 @CalledByNative("RTCConfiguration")
665 Integer getIceCheckIntervalWeakConnectivity() {
666 return iceCheckIntervalWeakConnectivityMs;
667 }
668
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100669 @Nullable
Qingsi Wange6826d22018-03-08 14:55:14 -0800670 @CalledByNative("RTCConfiguration")
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100671 Integer getIceCheckMinInterval() {
672 return iceCheckMinInterval;
673 }
674
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100675 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100676 @CalledByNative("RTCConfiguration")
Qingsi Wang22e623a2018-03-13 10:53:57 -0700677 Integer getIceUnwritableTimeout() {
678 return iceUnwritableTimeMs;
679 }
680
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100681 @Nullable
Qingsi Wang22e623a2018-03-13 10:53:57 -0700682 @CalledByNative("RTCConfiguration")
683 Integer getIceUnwritableMinChecks() {
684 return iceUnwritableMinChecks;
685 }
686
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100687 @Nullable
Qingsi Wang22e623a2018-03-13 10:53:57 -0700688 @CalledByNative("RTCConfiguration")
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800689 Integer getStunCandidateKeepaliveInterval() {
690 return stunCandidateKeepaliveIntervalMs;
691 }
692
693 @CalledByNative("RTCConfiguration")
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100694 boolean getDisableIPv6OnWifi() {
695 return disableIPv6OnWifi;
696 }
697
698 @CalledByNative("RTCConfiguration")
699 int getMaxIPv6Networks() {
700 return maxIPv6Networks;
701 }
702
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100703 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100704 @CalledByNative("RTCConfiguration")
705 IntervalRange getIceRegatherIntervalRange() {
706 return iceRegatherIntervalRange;
707 }
708
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100709 @Nullable
Magnus Jedvert9060eb12017-12-12 12:52:54 +0100710 @CalledByNative("RTCConfiguration")
711 TurnCustomizer getTurnCustomizer() {
712 return turnCustomizer;
713 }
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100714
715 @CalledByNative("RTCConfiguration")
716 boolean getDisableIpv6() {
717 return disableIpv6;
718 }
719
720 @CalledByNative("RTCConfiguration")
721 boolean getEnableDscp() {
722 return enableDscp;
723 }
724
725 @CalledByNative("RTCConfiguration")
726 boolean getEnableCpuOveruseDetection() {
727 return enableCpuOveruseDetection;
728 }
729
730 @CalledByNative("RTCConfiguration")
731 boolean getEnableRtpDataChannel() {
732 return enableRtpDataChannel;
733 }
734
735 @CalledByNative("RTCConfiguration")
736 boolean getSuspendBelowMinBitrate() {
737 return suspendBelowMinBitrate;
738 }
739
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100740 @Nullable
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100741 @CalledByNative("RTCConfiguration")
742 Integer getScreencastMinBitrate() {
743 return screencastMinBitrate;
744 }
745
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100746 @Nullable
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100747 @CalledByNative("RTCConfiguration")
748 Boolean getCombinedAudioVideoBwe() {
749 return combinedAudioVideoBwe;
750 }
751
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100752 @Nullable
Sami Kalliomäkie8b26cd2017-12-19 12:51:53 +0100753 @CalledByNative("RTCConfiguration")
754 Boolean getEnableDtlsSrtp() {
755 return enableDtlsSrtp;
756 }
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800757
758 @CalledByNative("RTCConfiguration")
759 AdapterType getNetworkPreference() {
760 return networkPreference;
761 }
Seth Hampsonc384e142018-03-06 15:47:10 -0800762
763 @CalledByNative("RTCConfiguration")
764 SdpSemantics getSdpSemantics() {
765 return sdpSemantics;
766 }
Zhi Huangb57e1692018-06-12 11:41:11 -0700767
768 @CalledByNative("RTCConfiguration")
769 boolean getActiveResetSrtpParams() {
770 return activeResetSrtpParams;
771 }
Piotr (Peter) Slatala09beff22018-10-17 07:22:40 -0700772
773 @CalledByNative("RTCConfiguration")
774 boolean getUseMediaTransport() {
775 return useMediaTransport;
776 }
Benjamin Wright8c27cca2018-10-25 10:16:44 -0700777
Bjorn Mellema9bbd862018-11-02 09:07:48 -0700778 @CalledByNative("RTCConfiguration")
779 boolean getUseMediaTransportForDataChannels() {
780 return useMediaTransportForDataChannels;
781 }
782
Benjamin Wright8c27cca2018-10-25 10:16:44 -0700783 @Nullable
784 @CalledByNative("RTCConfiguration")
785 CryptoOptions getCryptoOptions() {
786 return cryptoOptions;
787 }
Jiayang Liucac1b382015-04-30 12:35:24 -0700788 };
789
Magnus Jedvert6062f372017-11-16 16:53:12 +0100790 private final List<MediaStream> localStreams = new ArrayList<>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791 private final long nativePeerConnection;
Magnus Jedvert6062f372017-11-16 16:53:12 +0100792 private List<RtpSender> senders = new ArrayList<>();
793 private List<RtpReceiver> receivers = new ArrayList<>();
Seth Hampsonc384e142018-03-06 15:47:10 -0800794 private List<RtpTransceiver> transceivers = new ArrayList<>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795
Sami Kalliomäki1ece1ed2017-12-20 11:59:22 +0100796 /**
797 * Wraps a PeerConnection created by the factory. Can be used by clients that want to implement
798 * their PeerConnection creation in JNI.
799 */
800 public PeerConnection(NativePeerConnectionFactory factory) {
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +0100801 this(factory.createNativePeerConnection());
Sami Kalliomäki1ece1ed2017-12-20 11:59:22 +0100802 }
803
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +0100804 PeerConnection(long nativePeerConnection) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805 this.nativePeerConnection = nativePeerConnection;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806 }
807
808 // JsepInterface.
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100809 public SessionDescription getLocalDescription() {
810 return nativeGetLocalDescription();
811 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100813 public SessionDescription getRemoteDescription() {
814 return nativeGetRemoteDescription();
815 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816
Michael Iedema02137862018-10-09 15:30:01 +0200817 public RtcCertificatePem getCertificate() {
818 return nativeGetCertificate();
819 }
820
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100821 public DataChannel createDataChannel(String label, DataChannel.Init init) {
822 return nativeCreateDataChannel(label, init);
823 }
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000824
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100825 public void createOffer(SdpObserver observer, MediaConstraints constraints) {
826 nativeCreateOffer(observer, constraints);
827 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100829 public void createAnswer(SdpObserver observer, MediaConstraints constraints) {
830 nativeCreateAnswer(observer, constraints);
831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100833 public void setLocalDescription(SdpObserver observer, SessionDescription sdp) {
834 nativeSetLocalDescription(observer, sdp);
835 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100837 public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) {
838 nativeSetRemoteDescription(observer, sdp);
839 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840
Seth Hampsonc384e142018-03-06 15:47:10 -0800841 /**
842 * Enables/disables playout of received audio streams. Enabled by default.
843 *
844 * Note that even if playout is enabled, streams will only be played out if
845 * the appropriate SDP is also applied. The main purpose of this API is to
846 * be able to control the exact time when audio playout starts.
847 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100848 public void setAudioPlayout(boolean playout) {
849 nativeSetAudioPlayout(playout);
850 }
henrika5f6bf242017-11-01 11:06:56 +0100851
Seth Hampsonc384e142018-03-06 15:47:10 -0800852 /**
853 * Enables/disables recording of transmitted audio streams. Enabled by default.
854 *
855 * Note that even if recording is enabled, streams will only be recorded if
856 * the appropriate SDP is also applied. The main purpose of this API is to
857 * be able to control the exact time when audio recording starts.
858 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100859 public void setAudioRecording(boolean recording) {
860 nativeSetAudioRecording(recording);
861 }
henrika5f6bf242017-11-01 11:06:56 +0100862
deadbeef5d0b6d82017-01-09 16:05:28 -0800863 public boolean setConfiguration(RTCConfiguration config) {
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +0100864 return nativeSetConfiguration(config);
deadbeef5d0b6d82017-01-09 16:05:28 -0800865 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866
867 public boolean addIceCandidate(IceCandidate candidate) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100868 return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869 }
870
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700871 public boolean removeIceCandidates(final IceCandidate[] candidates) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100872 return nativeRemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700873 }
874
Seth Hampsonc384e142018-03-06 15:47:10 -0800875 /**
876 * Adds a new MediaStream to be sent on this peer connection.
877 * Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please
878 * use addTrack instead.
879 */
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000880 public boolean addStream(MediaStream stream) {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200881 boolean ret = nativeAddLocalStream(stream.getNativeMediaStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882 if (!ret) {
883 return false;
884 }
885 localStreams.add(stream);
886 return true;
887 }
888
Seth Hampsonc384e142018-03-06 15:47:10 -0800889 /**
890 * Removes the given media stream from this peer connection.
891 * This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use
892 * removeTrack instead.
893 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894 public void removeStream(MediaStream stream) {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200895 nativeRemoveLocalStream(stream.getNativeMediaStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 localStreams.remove(stream);
897 }
898
deadbeef7a246882017-08-09 08:40:10 -0700899 /**
900 * Creates an RtpSender without a track.
Seth Hampsonc384e142018-03-06 15:47:10 -0800901 *
902 * <p>This method allows an application to cause the PeerConnection to negotiate
deadbeef7a246882017-08-09 08:40:10 -0700903 * sending/receiving a specific media type, but without having a track to
904 * send yet.
Seth Hampsonc384e142018-03-06 15:47:10 -0800905 *
906 * <p>When the application does want to begin sending a track, it can call
deadbeef7a246882017-08-09 08:40:10 -0700907 * RtpSender.setTrack, which doesn't require any additional SDP negotiation.
Seth Hampsonc384e142018-03-06 15:47:10 -0800908 *
909 * <p>Example use:
deadbeef7a246882017-08-09 08:40:10 -0700910 * <pre>
911 * {@code
912 * audioSender = pc.createSender("audio", "stream1");
913 * videoSender = pc.createSender("video", "stream1");
914 * // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate
915 * // media parameters....
916 * // Later, when the endpoint is ready to actually begin sending:
917 * audioSender.setTrack(audioTrack, false);
918 * videoSender.setTrack(videoTrack, false);
919 * }
920 * </pre>
Seth Hampsonc384e142018-03-06 15:47:10 -0800921 * <p>Note: This corresponds most closely to "addTransceiver" in the official
deadbeef7a246882017-08-09 08:40:10 -0700922 * WebRTC API, in that it creates a sender without a track. It was
923 * implemented before addTransceiver because it provides useful
924 * functionality, and properly implementing transceivers would have required
925 * a great deal more work.
926 *
Seth Hampsonc384e142018-03-06 15:47:10 -0800927 * <p>Note: This is only available with SdpSemantics.PLAN_B specified. Please use
928 * addTransceiver instead.
929 *
deadbeef7a246882017-08-09 08:40:10 -0700930 * @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or
931 * "video").
932 * @param stream_id The ID of the MediaStream that this sender's track will
933 * be associated with when SDP is applied to the remote
934 * PeerConnection. If createSender is used to create an
935 * audio and video sender that should be synchronized, they
936 * should use the same stream ID.
937 * @return A new RtpSender object if successful, or null otherwise.
938 */
deadbeefbd7d8f72015-12-18 16:58:44 -0800939 public RtpSender createSender(String kind, String stream_id) {
Seth Hampsonc384e142018-03-06 15:47:10 -0800940 RtpSender newSender = nativeCreateSender(kind, stream_id);
941 if (newSender != null) {
942 senders.add(newSender);
deadbeefee524f72015-12-02 11:27:40 -0800943 }
Seth Hampsonc384e142018-03-06 15:47:10 -0800944 return newSender;
deadbeefee524f72015-12-02 11:27:40 -0800945 }
946
Seth Hampsonc384e142018-03-06 15:47:10 -0800947 /**
948 * Gets all RtpSenders associated with this peer connection.
949 * Note that calling getSenders will dispose of the senders previously
950 * returned.
951 */
deadbeef4139c0f2015-10-06 12:29:25 -0700952 public List<RtpSender> getSenders() {
953 for (RtpSender sender : senders) {
954 sender.dispose();
955 }
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100956 senders = nativeGetSenders();
deadbeef4139c0f2015-10-06 12:29:25 -0700957 return Collections.unmodifiableList(senders);
958 }
959
Seth Hampsonc384e142018-03-06 15:47:10 -0800960 /**
961 * Gets all RtpReceivers associated with this peer connection.
962 * Note that calling getReceivers will dispose of the receivers previously
963 * returned.
964 */
deadbeef4139c0f2015-10-06 12:29:25 -0700965 public List<RtpReceiver> getReceivers() {
966 for (RtpReceiver receiver : receivers) {
967 receiver.dispose();
968 }
Magnus Jedvert84d8ae52017-12-20 15:12:10 +0100969 receivers = nativeGetReceivers();
deadbeef4139c0f2015-10-06 12:29:25 -0700970 return Collections.unmodifiableList(receivers);
971 }
972
Seth Hampsonc384e142018-03-06 15:47:10 -0800973 /**
974 * Gets all RtpTransceivers associated with this peer connection.
975 * Note that calling getTransceivers will dispose of the transceivers previously
976 * returned.
977 * Note: This is only available with SdpSemantics.UNIFIED_PLAN specified.
978 */
979 public List<RtpTransceiver> getTransceivers() {
980 for (RtpTransceiver transceiver : transceivers) {
981 transceiver.dispose();
982 }
983 transceivers = nativeGetTransceivers();
984 return Collections.unmodifiableList(transceivers);
985 }
986
987 /**
988 * Adds a new media stream track to be sent on this peer connection, and returns
989 * the newly created RtpSender. If streamIds are specified, the RtpSender will
990 * be associated with the streams specified in the streamIds list.
991 *
992 * @throws IllegalStateException if an error accors in C++ addTrack.
993 * An error can occur if:
994 * - A sender already exists for the track.
995 * - The peer connection is closed.
996 */
997 public RtpSender addTrack(MediaStreamTrack track) {
998 return addTrack(track, Collections.emptyList());
999 }
1000
1001 public RtpSender addTrack(MediaStreamTrack track, List<String> streamIds) {
1002 if (track == null || streamIds == null) {
1003 throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
1004 }
Sami Kalliomäkiee05e902018-09-28 14:38:21 +02001005 RtpSender newSender = nativeAddTrack(track.getNativeMediaStreamTrack(), streamIds);
Seth Hampsonc384e142018-03-06 15:47:10 -08001006 if (newSender == null) {
1007 throw new IllegalStateException("C++ addTrack failed.");
1008 }
1009 senders.add(newSender);
1010 return newSender;
1011 }
1012
1013 /**
1014 * Stops sending media from sender. The sender will still appear in getSenders. Future
1015 * calls to createOffer will mark the m section for the corresponding transceiver as
1016 * receive only or inactive, as defined in JSEP. Returns true on success.
1017 */
1018 public boolean removeTrack(RtpSender sender) {
1019 if (sender == null) {
1020 throw new NullPointerException("No RtpSender specified for removeTrack.");
1021 }
Sami Kalliomäkiee05e902018-09-28 14:38:21 +02001022 return nativeRemoveTrack(sender.getNativeRtpSender());
Seth Hampsonc384e142018-03-06 15:47:10 -08001023 }
1024
1025 /**
1026 * Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a
1027 * transceiver will cause future calls to CreateOffer to add a media description
1028 * for the corresponding transceiver.
1029 *
1030 * <p>The initial value of |mid| in the returned transceiver is null. Setting a
1031 * new session description may change it to a non-null value.
1032 *
1033 * <p>https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
1034 *
1035 * <p>If a MediaStreamTrack is specified then a transceiver will be added with a
1036 * sender set to transmit the given track. The kind
1037 * of the transceiver (and sender/receiver) will be derived from the kind of
1038 * the track.
1039 *
1040 * <p>If MediaType is specified then a transceiver will be added based upon that type.
1041 * This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO.
1042 *
1043 * <p>Optionally, an RtpTransceiverInit structure can be specified to configure
1044 * the transceiver from construction. If not specified, the transceiver will
1045 * default to having a direction of kSendRecv and not be part of any streams.
1046 *
1047 * <p>Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified.
1048 * @throws IllegalStateException if an error accors in C++ addTransceiver
1049 */
1050 public RtpTransceiver addTransceiver(MediaStreamTrack track) {
1051 return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit());
1052 }
1053
1054 public RtpTransceiver addTransceiver(
Sami Kalliomäkie7592d82018-03-22 13:32:44 +01001055 MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init) {
Seth Hampsonc384e142018-03-06 15:47:10 -08001056 if (track == null) {
1057 throw new NullPointerException("No MediaStreamTrack specified for addTransceiver.");
1058 }
1059 if (init == null) {
1060 init = new RtpTransceiver.RtpTransceiverInit();
1061 }
Sami Kalliomäkiee05e902018-09-28 14:38:21 +02001062 RtpTransceiver newTransceiver =
1063 nativeAddTransceiverWithTrack(track.getNativeMediaStreamTrack(), init);
Seth Hampsonc384e142018-03-06 15:47:10 -08001064 if (newTransceiver == null) {
1065 throw new IllegalStateException("C++ addTransceiver failed.");
1066 }
1067 transceivers.add(newTransceiver);
1068 return newTransceiver;
1069 }
1070
1071 public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) {
1072 return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit());
1073 }
1074
1075 public RtpTransceiver addTransceiver(
Sami Kalliomäkie7592d82018-03-22 13:32:44 +01001076 MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init) {
Seth Hampsonc384e142018-03-06 15:47:10 -08001077 if (mediaType == null) {
1078 throw new NullPointerException("No MediaType specified for addTransceiver.");
1079 }
1080 if (init == null) {
1081 init = new RtpTransceiver.RtpTransceiverInit();
1082 }
1083 RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init);
1084 if (newTransceiver == null) {
1085 throw new IllegalStateException("C++ addTransceiver failed.");
1086 }
1087 transceivers.add(newTransceiver);
1088 return newTransceiver;
1089 }
1090
deadbeef82215872017-04-18 10:27:51 -07001091 // Older, non-standard implementation of getStats.
1092 @Deprecated
Sami Kalliomäkie7592d82018-03-22 13:32:44 +01001093 public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +02001094 return nativeOldGetStats(observer, (track == null) ? 0 : track.getNativeMediaStreamTrack());
deadbeef82215872017-04-18 10:27:51 -07001095 }
1096
Seth Hampsonc384e142018-03-06 15:47:10 -08001097 /**
1098 * Gets stats using the new stats collection API, see webrtc/api/stats/. These
1099 * will replace old stats collection API when the new API has matured enough.
1100 */
deadbeef82215872017-04-18 10:27:51 -07001101 public void getStats(RTCStatsCollectorCallback callback) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001102 nativeNewGetStats(callback);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001103 }
1104
Seth Hampsonc384e142018-03-06 15:47:10 -08001105 /**
1106 * Limits the bandwidth allocated for all RTP streams sent by this
1107 * PeerConnection. Pass null to leave a value unchanged.
1108 */
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001109 public boolean setBitrate(Integer min, Integer current, Integer max) {
1110 return nativeSetBitrate(min, current, max);
1111 }
zsteind89b0bc2017-08-03 11:11:40 -07001112
Seth Hampsonc384e142018-03-06 15:47:10 -08001113 /**
1114 * Starts recording an RTC event log.
1115 *
1116 * Ownership of the file is transfered to the native code. If an RTC event
1117 * log is already being recorded, it will be stopped and a new one will start
1118 * using the provided file. Logging will continue until the stopRtcEventLog
1119 * function is called. The max_size_bytes argument is ignored, it is added
1120 * for future use.
1121 */
ivoc0c6f0f62016-07-06 04:34:23 -07001122 public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001123 return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
ivoc14d5dbe2016-07-04 07:06:55 -07001124 }
1125
Seth Hampsonc384e142018-03-06 15:47:10 -08001126 /**
1127 * Stops recording an RTC event log. If no RTC event log is currently being
1128 * recorded, this call will have no effect.
1129 */
ivoc14d5dbe2016-07-04 07:06:55 -07001130 public void stopRtcEventLog() {
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001131 nativeStopRtcEventLog();
ivoc14d5dbe2016-07-04 07:06:55 -07001132 }
1133
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001134 // TODO(fischman): add support for DTMF-related methods once that API
1135 // stabilizes.
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001136 public SignalingState signalingState() {
1137 return nativeSignalingState();
1138 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001139
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001140 public IceConnectionState iceConnectionState() {
1141 return nativeIceConnectionState();
1142 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001143
Jonas Olssonf01d8c82018-11-08 15:19:04 +01001144 public PeerConnectionState connectionState() {
1145 return nativeConnectionState();
1146 }
1147
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001148 public IceGatheringState iceGatheringState() {
1149 return nativeIceGatheringState();
1150 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001151
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001152 public void close() {
1153 nativeClose();
1154 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001155
deadbeef43697f62017-09-12 10:52:14 -07001156 /**
1157 * Free native resources associated with this PeerConnection instance.
Seth Hampsonc384e142018-03-06 15:47:10 -08001158 *
deadbeef43697f62017-09-12 10:52:14 -07001159 * This method removes a reference count from the C++ PeerConnection object,
1160 * which should result in it being destroyed. It also calls equivalent
1161 * "dispose" methods on the Java objects attached to this PeerConnection
1162 * (streams, senders, receivers), such that their associated C++ objects
1163 * will also be destroyed.
Seth Hampsonc384e142018-03-06 15:47:10 -08001164 *
1165 * <p>Note that this method cannot be safely called from an observer callback
deadbeef43697f62017-09-12 10:52:14 -07001166 * (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for
1167 * example, destroy the PeerConnection after an "ICE failed" callback, you
1168 * must do this asynchronously (in other words, unwind the stack first). See
1169 * <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=3721">bug
1170 * 3721</a> for more details.
1171 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001172 public void dispose() {
1173 close();
1174 for (MediaStream stream : localStreams) {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +02001175 nativeRemoveLocalStream(stream.getNativeMediaStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001176 stream.dispose();
1177 }
1178 localStreams.clear();
deadbeef4139c0f2015-10-06 12:29:25 -07001179 for (RtpSender sender : senders) {
1180 sender.dispose();
1181 }
1182 senders.clear();
1183 for (RtpReceiver receiver : receivers) {
1184 receiver.dispose();
1185 }
Seth Hampsonc384e142018-03-06 15:47:10 -08001186 for (RtpTransceiver transceiver : transceivers) {
1187 transceiver.dispose();
1188 }
1189 transceivers.clear();
deadbeef4139c0f2015-10-06 12:29:25 -07001190 receivers.clear();
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001191 nativeFreeOwnedPeerConnection(nativePeerConnection);
1192 }
1193
1194 /** Returns a pointer to the native webrtc::PeerConnectionInterface. */
1195 public long getNativePeerConnection() {
1196 return nativeGetNativePeerConnection();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001197 }
1198
Magnus Jedvert9060eb12017-12-12 12:52:54 +01001199 @CalledByNative
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001200 long getNativeOwnedPeerConnection() {
Magnus Jedvert9060eb12017-12-12 12:52:54 +01001201 return nativePeerConnection;
1202 }
1203
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001204 public static long createNativePeerConnectionObserver(Observer observer) {
1205 return nativeCreatePeerConnectionObserver(observer);
1206 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001208 private native long nativeGetNativePeerConnection();
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001209 private native SessionDescription nativeGetLocalDescription();
1210 private native SessionDescription nativeGetRemoteDescription();
Michael Iedema02137862018-10-09 15:30:01 +02001211 private native RtcCertificatePem nativeGetCertificate();
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001212 private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init);
1213 private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints);
1214 private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints);
1215 private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp);
1216 private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp);
1217 private native void nativeSetAudioPlayout(boolean playout);
1218 private native void nativeSetAudioRecording(boolean recording);
1219 private native boolean nativeSetBitrate(Integer min, Integer current, Integer max);
1220 private native SignalingState nativeSignalingState();
1221 private native IceConnectionState nativeIceConnectionState();
Jonas Olssonf01d8c82018-11-08 15:19:04 +01001222 private native PeerConnectionState nativeConnectionState();
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001223 private native IceGatheringState nativeIceGatheringState();
1224 private native void nativeClose();
1225 private static native long nativeCreatePeerConnectionObserver(Observer observer);
Sami Kalliomäkice5c19a2018-01-15 09:28:34 +01001226 private static native void nativeFreeOwnedPeerConnection(long ownedPeerConnection);
1227 private native boolean nativeSetConfiguration(RTCConfiguration config);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001228 private native boolean nativeAddIceCandidate(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001229 String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001230 private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
1231 private native boolean nativeAddLocalStream(long stream);
1232 private native void nativeRemoveLocalStream(long stream);
1233 private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
1234 private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
1235 private native RtpSender nativeCreateSender(String kind, String stream_id);
1236 private native List<RtpSender> nativeGetSenders();
1237 private native List<RtpReceiver> nativeGetReceivers();
Seth Hampsonc384e142018-03-06 15:47:10 -08001238 private native List<RtpTransceiver> nativeGetTransceivers();
1239 private native RtpSender nativeAddTrack(long track, List<String> streamIds);
1240 private native boolean nativeRemoveTrack(long sender);
1241 private native RtpTransceiver nativeAddTransceiverWithTrack(
1242 long track, RtpTransceiver.RtpTransceiverInit init);
1243 private native RtpTransceiver nativeAddTransceiverOfType(
1244 MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +01001245 private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
1246 private native void nativeStopRtcEventLog();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001247}