blob: 9bc4ebf30965b7b28ca830f653d86050350e35e6 [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;
16
17/**
18 * Java-land version of the PeerConnection APIs; wraps the C++ API
19 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the
20 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
21 * http://www.w3.org/TR/mediacapture-streams/
22 */
23public class PeerConnection {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024 /** Tracks PeerConnectionInterface::IceGatheringState */
sakalb6760f92016-09-29 04:12:44 -070025 public enum IceGatheringState { NEW, GATHERING, COMPLETE }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000026
27 /** Tracks PeerConnectionInterface::IceConnectionState */
28 public enum IceConnectionState {
sakalb6760f92016-09-29 04:12:44 -070029 NEW,
30 CHECKING,
31 CONNECTED,
32 COMPLETED,
33 FAILED,
34 DISCONNECTED,
35 CLOSED
36 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
hnsl04833622017-01-09 08:35:45 -080038 /** Tracks PeerConnectionInterface::TlsCertPolicy */
39 public enum TlsCertPolicy {
40 TLS_CERT_POLICY_SECURE,
41 TLS_CERT_POLICY_INSECURE_NO_CHECK,
42 }
43
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044 /** Tracks PeerConnectionInterface::SignalingState */
45 public enum SignalingState {
sakalb6760f92016-09-29 04:12:44 -070046 STABLE,
47 HAVE_LOCAL_OFFER,
48 HAVE_LOCAL_PRANSWER,
49 HAVE_REMOTE_OFFER,
50 HAVE_REMOTE_PRANSWER,
51 CLOSED
52 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053
54 /** Java version of PeerConnectionObserver. */
55 public static interface Observer {
56 /** Triggered when the SignalingState changes. */
57 public void onSignalingChange(SignalingState newState);
58
59 /** Triggered when the IceConnectionState changes. */
60 public void onIceConnectionChange(IceConnectionState newState);
61
Peter Thatcher54360512015-07-08 11:08:35 -070062 /** Triggered when the ICE connection receiving status changes. */
63 public void onIceConnectionReceivingChange(boolean receiving);
64
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 /** Triggered when the IceGatheringState changes. */
66 public void onIceGatheringChange(IceGatheringState newState);
67
68 /** Triggered when a new ICE candidate has been found. */
69 public void onIceCandidate(IceCandidate candidate);
70
Honghai Zhang7fb69db2016-03-14 11:59:18 -070071 /** Triggered when some ICE candidates have been removed. */
72 public void onIceCandidatesRemoved(IceCandidate[] candidates);
73
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 /** Triggered when media is received on a new stream from remote peer. */
75 public void onAddStream(MediaStream stream);
76
77 /** Triggered when a remote peer close a stream. */
78 public void onRemoveStream(MediaStream stream);
henrike@webrtc.org723d6832013-07-12 16:04:50 +000079
80 /** Triggered when a remote peer opens a DataChannel. */
81 public void onDataChannel(DataChannel dataChannel);
fischman@webrtc.orgd7568a02014-01-13 22:04:12 +000082
83 /** Triggered when renegotiation is necessary. */
84 public void onRenegotiationNeeded();
zhihuangdcccda72016-12-21 14:08:03 -080085
86 /**
87 * Triggered when a new track is signaled by the remote peer, as a result of
88 * setRemoteDescription.
89 */
90 public void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091 }
92
93 /** Java version of PeerConnectionInterface.IceServer. */
94 public static class IceServer {
Emad Omaradab1d2d2017-06-16 15:43:11 -070095 // List of URIs associated with this server. Valid formats are described
96 // in RFC7064 and RFC7065, and more may be added in the future. The "host"
97 // part of the URI may contain either an IP address or a hostname.
korniltsev.anatoly0ea03102017-09-11 06:41:38 -070098 @Deprecated public final String uri;
99 public final List<String> urls;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100 public final String username;
101 public final String password;
hnsl04833622017-01-09 08:35:45 -0800102 public final TlsCertPolicy tlsCertPolicy;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103
Emad Omaradab1d2d2017-06-16 15:43:11 -0700104 // If the URIs in |urls| only contain IP addresses, this field can be used
105 // to indicate the hostname, which may be necessary for TLS (using the SNI
106 // extension). If |urls| itself contains the hostname, this isn't
107 // necessary.
108 public final String hostname;
109
Diogo Real1dca9d52017-08-29 12:18:32 -0700110 // List of protocols to be used in the TLS ALPN extension.
111 public final List<String> tlsAlpnProtocols;
112
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700113 // List of elliptic curves to be used in the TLS elliptic curves extension.
114 // Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
115 public final List<String> tlsEllipticCurves;
116
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117 /** Convenience constructor for STUN servers. */
Diogo Real05ea2b32017-08-31 00:12:58 -0700118 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119 public IceServer(String uri) {
120 this(uri, "", "");
121 }
122
Diogo Real05ea2b32017-08-31 00:12:58 -0700123 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124 public IceServer(String uri, String username, String password) {
hnsl04833622017-01-09 08:35:45 -0800125 this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE);
126 }
127
Diogo Real05ea2b32017-08-31 00:12:58 -0700128 @Deprecated
hnsl04833622017-01-09 08:35:45 -0800129 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) {
Emad Omaradab1d2d2017-06-16 15:43:11 -0700130 this(uri, username, password, tlsCertPolicy, "");
131 }
132
Diogo Real05ea2b32017-08-31 00:12:58 -0700133 @Deprecated
Emad Omaradab1d2d2017-06-16 15:43:11 -0700134 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
135 String hostname) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700136 this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null,
137 null);
Diogo Real1dca9d52017-08-29 12:18:32 -0700138 }
139
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700140 private IceServer(String uri, List<String> urls, String username, String password,
141 TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols,
142 List<String> tlsEllipticCurves) {
143 if (uri == null || urls == null || urls.isEmpty()) {
144 throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()");
145 }
146 for (String it : urls) {
147 if (it == null) {
148 throw new IllegalArgumentException("urls element is null: " + urls);
149 }
150 }
151 if (username == null) {
152 throw new IllegalArgumentException("username == null");
153 }
154 if (password == null) {
155 throw new IllegalArgumentException("password == null");
156 }
157 if (hostname == null) {
158 throw new IllegalArgumentException("hostname == null");
159 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 this.uri = uri;
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700161 this.urls = urls;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162 this.username = username;
163 this.password = password;
hnsl04833622017-01-09 08:35:45 -0800164 this.tlsCertPolicy = tlsCertPolicy;
Emad Omaradab1d2d2017-06-16 15:43:11 -0700165 this.hostname = hostname;
Diogo Real1dca9d52017-08-29 12:18:32 -0700166 this.tlsAlpnProtocols = tlsAlpnProtocols;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700167 this.tlsEllipticCurves = tlsEllipticCurves;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168 }
169
Sami Kalliomäkibde473e2017-10-30 13:34:41 +0100170 @Override
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 public String toString() {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700172 return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700173 + "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
Diogo Real1dca9d52017-08-29 12:18:32 -0700174 }
175
176 public static Builder builder(String uri) {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700177 return new Builder(Collections.singletonList(uri));
178 }
179
180 public static Builder builder(List<String> urls) {
181 return new Builder(urls);
Diogo Real1dca9d52017-08-29 12:18:32 -0700182 }
183
184 public static class Builder {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700185 private final List<String> urls;
Diogo Real1dca9d52017-08-29 12:18:32 -0700186 private String username = "";
187 private String password = "";
188 private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
189 private String hostname = "";
190 private List<String> tlsAlpnProtocols;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700191 private List<String> tlsEllipticCurves;
Diogo Real1dca9d52017-08-29 12:18:32 -0700192
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700193 private Builder(List<String> urls) {
194 if (urls == null || urls.isEmpty()) {
195 throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls);
196 }
197 this.urls = urls;
Diogo Real1dca9d52017-08-29 12:18:32 -0700198 }
199
200 public Builder setUsername(String username) {
201 this.username = username;
202 return this;
203 }
204
205 public Builder setPassword(String password) {
206 this.password = password;
207 return this;
208 }
209
210 public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) {
211 this.tlsCertPolicy = tlsCertPolicy;
212 return this;
213 }
214
215 public Builder setHostname(String hostname) {
216 this.hostname = hostname;
217 return this;
218 }
219
220 public Builder setTlsAlpnProtocols(List<String> tlsAlpnProtocols) {
221 this.tlsAlpnProtocols = tlsAlpnProtocols;
222 return this;
223 }
224
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700225 public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
226 this.tlsEllipticCurves = tlsEllipticCurves;
227 return this;
228 }
229
Diogo Real1dca9d52017-08-29 12:18:32 -0700230 public IceServer createIceServer() {
korniltsev.anatoly0ea03102017-09-11 06:41:38 -0700231 return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname,
232 tlsAlpnProtocols, tlsEllipticCurves);
Diogo Real1dca9d52017-08-29 12:18:32 -0700233 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 }
235 }
236
Jiayang Liucac1b382015-04-30 12:35:24 -0700237 /** Java version of PeerConnectionInterface.IceTransportsType */
sakalb6760f92016-09-29 04:12:44 -0700238 public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }
Jiayang Liucac1b382015-04-30 12:35:24 -0700239
240 /** Java version of PeerConnectionInterface.BundlePolicy */
sakalb6760f92016-09-29 04:12:44 -0700241 public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }
Jiayang Liucac1b382015-04-30 12:35:24 -0700242
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700243 /** Java version of PeerConnectionInterface.RtcpMuxPolicy */
sakalb6760f92016-09-29 04:12:44 -0700244 public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }
glaznev97579a42015-09-01 11:31:27 -0700245
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700246 /** Java version of PeerConnectionInterface.TcpCandidatePolicy */
sakalb6760f92016-09-29 04:12:44 -0700247 public enum TcpCandidatePolicy { ENABLED, DISABLED }
Jiayang Liucac1b382015-04-30 12:35:24 -0700248
honghaiz60347052016-05-31 18:29:12 -0700249 /** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
sakalb6760f92016-09-29 04:12:44 -0700250 public enum CandidateNetworkPolicy { ALL, LOW_COST }
honghaiz60347052016-05-31 18:29:12 -0700251
glaznev97579a42015-09-01 11:31:27 -0700252 /** Java version of rtc::KeyType */
sakalb6760f92016-09-29 04:12:44 -0700253 public enum KeyType { RSA, ECDSA }
glaznev97579a42015-09-01 11:31:27 -0700254
honghaiz1f429e32015-09-28 07:57:34 -0700255 /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
sakalb6760f92016-09-29 04:12:44 -0700256 public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }
honghaiz1f429e32015-09-28 07:57:34 -0700257
Steve Antond960a0c2017-07-17 12:33:07 -0700258 /** Java version of rtc::IntervalRange */
259 public static class IntervalRange {
260 private final int min;
261 private final int max;
262
263 public IntervalRange(int min, int max) {
264 this.min = min;
265 this.max = max;
266 }
267
268 public int getMin() {
269 return min;
270 }
271
272 public int getMax() {
273 return max;
274 }
275 }
276
Jiayang Liucac1b382015-04-30 12:35:24 -0700277 /** Java version of PeerConnectionInterface.RTCConfiguration */
278 public static class RTCConfiguration {
279 public IceTransportsType iceTransportsType;
280 public List<IceServer> iceServers;
281 public BundlePolicy bundlePolicy;
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700282 public RtcpMuxPolicy rtcpMuxPolicy;
Jiayang Liucac1b382015-04-30 12:35:24 -0700283 public TcpCandidatePolicy tcpCandidatePolicy;
honghaiz60347052016-05-31 18:29:12 -0700284 public CandidateNetworkPolicy candidateNetworkPolicy;
Henrik Lundin64dad832015-05-11 12:44:23 +0200285 public int audioJitterBufferMaxPackets;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200286 public boolean audioJitterBufferFastAccelerate;
honghaiz4edc39c2015-09-01 09:53:56 -0700287 public int iceConnectionReceivingTimeout;
Honghai Zhang381b4212015-12-04 12:24:03 -0800288 public int iceBackupCandidatePairPingInterval;
glaznev97579a42015-09-01 11:31:27 -0700289 public KeyType keyType;
honghaiz1f429e32015-09-28 07:57:34 -0700290 public ContinualGatheringPolicy continualGatheringPolicy;
deadbeefbe0c96f2016-05-18 16:20:14 -0700291 public int iceCandidatePoolSize;
Honghai Zhangd78ecf72016-07-01 14:40:40 -0700292 public boolean pruneTurnPorts;
Taylor Brandstettere9851112016-07-01 11:11:13 -0700293 public boolean presumeWritableWhenFullyRelayed;
skvlad51072462017-02-02 11:50:14 -0800294 public Integer iceCheckMinInterval;
zhihuangb09b3f92017-03-07 14:40:51 -0800295 public boolean disableIPv6OnWifi;
deadbeef28e29192017-07-27 09:14:38 -0700296 // By default, PeerConnection will use a limited number of IPv6 network
297 // interfaces, in order to avoid too many ICE candidate pairs being created
298 // and delaying ICE completion.
299 //
300 // Can be set to Integer.MAX_VALUE to effectively disable the limit.
301 public int maxIPv6Networks;
Steve Antond960a0c2017-07-17 12:33:07 -0700302 public IntervalRange iceRegatherIntervalRange;
Jiayang Liucac1b382015-04-30 12:35:24 -0700303
Jonas Orelandbdcee282017-10-10 14:01:40 +0200304 // This is an optional wrapper for the C++ webrtc::TurnCustomizer.
305 public TurnCustomizer turnCustomizer;
306
deadbeef28e29192017-07-27 09:14:38 -0700307 // TODO(deadbeef): Instead of duplicating the defaults here, we should do
308 // something to pick up the defaults from C++. The Objective-C equivalent
309 // of RTCConfiguration does that.
Jiayang Liucac1b382015-04-30 12:35:24 -0700310 public RTCConfiguration(List<IceServer> iceServers) {
311 iceTransportsType = IceTransportsType.ALL;
312 bundlePolicy = BundlePolicy.BALANCED;
zhihuang4dfb8ce2016-11-23 10:30:12 -0800313 rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE;
Jiayang Liucac1b382015-04-30 12:35:24 -0700314 tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
Sami Kalliomäki9828beb2017-10-26 16:21:22 +0200315 candidateNetworkPolicy = CandidateNetworkPolicy.ALL;
Jiayang Liucac1b382015-04-30 12:35:24 -0700316 this.iceServers = iceServers;
Henrik Lundin64dad832015-05-11 12:44:23 +0200317 audioJitterBufferMaxPackets = 50;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200318 audioJitterBufferFastAccelerate = false;
honghaiz4edc39c2015-09-01 09:53:56 -0700319 iceConnectionReceivingTimeout = -1;
Honghai Zhang381b4212015-12-04 12:24:03 -0800320 iceBackupCandidatePairPingInterval = -1;
glaznev97579a42015-09-01 11:31:27 -0700321 keyType = KeyType.ECDSA;
honghaiz1f429e32015-09-28 07:57:34 -0700322 continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE;
deadbeefbe0c96f2016-05-18 16:20:14 -0700323 iceCandidatePoolSize = 0;
Honghai Zhangd78ecf72016-07-01 14:40:40 -0700324 pruneTurnPorts = false;
Taylor Brandstettere9851112016-07-01 11:11:13 -0700325 presumeWritableWhenFullyRelayed = false;
skvlad51072462017-02-02 11:50:14 -0800326 iceCheckMinInterval = null;
zhihuangb09b3f92017-03-07 14:40:51 -0800327 disableIPv6OnWifi = false;
deadbeef28e29192017-07-27 09:14:38 -0700328 maxIPv6Networks = 5;
Steve Antond960a0c2017-07-17 12:33:07 -0700329 iceRegatherIntervalRange = null;
Jiayang Liucac1b382015-04-30 12:35:24 -0700330 }
331 };
332
Magnus Jedvert6062f372017-11-16 16:53:12 +0100333 private final List<MediaStream> localStreams = new ArrayList<>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 private final long nativePeerConnection;
335 private final long nativeObserver;
Magnus Jedvert6062f372017-11-16 16:53:12 +0100336 private List<RtpSender> senders = new ArrayList<>();
337 private List<RtpReceiver> receivers = new ArrayList<>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000338
339 PeerConnection(long nativePeerConnection, long nativeObserver) {
340 this.nativePeerConnection = nativePeerConnection;
341 this.nativeObserver = nativeObserver;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 }
343
344 // JsepInterface.
345 public native SessionDescription getLocalDescription();
346
347 public native SessionDescription getRemoteDescription();
348
sakalb6760f92016-09-29 04:12:44 -0700349 public native DataChannel createDataChannel(String label, DataChannel.Init init);
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000350
sakalb6760f92016-09-29 04:12:44 -0700351 public native void createOffer(SdpObserver observer, MediaConstraints constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352
sakalb6760f92016-09-29 04:12:44 -0700353 public native void createAnswer(SdpObserver observer, MediaConstraints constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354
sakalb6760f92016-09-29 04:12:44 -0700355 public native void setLocalDescription(SdpObserver observer, SessionDescription sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356
sakalb6760f92016-09-29 04:12:44 -0700357 public native void setRemoteDescription(SdpObserver observer, SessionDescription sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358
henrika5f6bf242017-11-01 11:06:56 +0100359 // True if remote audio should be played out. Defaults to true.
360 // Note that even if playout is enabled, streams will only be played out if
361 // the appropriate SDP is also applied. The main purpose of this API is to
362 // be able to control the exact time when audio playout starts.
363 public native void setAudioPlayout(boolean playout);
364
365 // True if local audio shall be recorded. Defaults to true.
366 // Note that even if recording is enabled, streams will only be recorded if
367 // the appropriate SDP is also applied. The main purpose of this API is to
368 // be able to control the exact time when audio recording starts.
369 public native void setAudioRecording(boolean recording);
370
deadbeef5d0b6d82017-01-09 16:05:28 -0800371 public boolean setConfiguration(RTCConfiguration config) {
372 return nativeSetConfiguration(config, nativeObserver);
373 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374
375 public boolean addIceCandidate(IceCandidate candidate) {
sakalb6760f92016-09-29 04:12:44 -0700376 return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 }
378
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700379 public boolean removeIceCandidates(final IceCandidate[] candidates) {
380 return nativeRemoveIceCandidates(candidates);
381 }
382
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000383 public boolean addStream(MediaStream stream) {
384 boolean ret = nativeAddLocalStream(stream.nativeStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385 if (!ret) {
386 return false;
387 }
388 localStreams.add(stream);
389 return true;
390 }
391
392 public void removeStream(MediaStream stream) {
393 nativeRemoveLocalStream(stream.nativeStream);
394 localStreams.remove(stream);
395 }
396
deadbeef7a246882017-08-09 08:40:10 -0700397 /**
398 * Creates an RtpSender without a track.
399 * <p>
400 * This method allows an application to cause the PeerConnection to negotiate
401 * sending/receiving a specific media type, but without having a track to
402 * send yet.
403 * <p>
404 * When the application does want to begin sending a track, it can call
405 * RtpSender.setTrack, which doesn't require any additional SDP negotiation.
406 * <p>
407 * Example use:
408 * <pre>
409 * {@code
410 * audioSender = pc.createSender("audio", "stream1");
411 * videoSender = pc.createSender("video", "stream1");
412 * // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate
413 * // media parameters....
414 * // Later, when the endpoint is ready to actually begin sending:
415 * audioSender.setTrack(audioTrack, false);
416 * videoSender.setTrack(videoTrack, false);
417 * }
418 * </pre>
419 * Note: This corresponds most closely to "addTransceiver" in the official
420 * WebRTC API, in that it creates a sender without a track. It was
421 * implemented before addTransceiver because it provides useful
422 * functionality, and properly implementing transceivers would have required
423 * a great deal more work.
424 *
425 * @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or
426 * "video").
427 * @param stream_id The ID of the MediaStream that this sender's track will
428 * be associated with when SDP is applied to the remote
429 * PeerConnection. If createSender is used to create an
430 * audio and video sender that should be synchronized, they
431 * should use the same stream ID.
432 * @return A new RtpSender object if successful, or null otherwise.
433 */
deadbeefbd7d8f72015-12-18 16:58:44 -0800434 public RtpSender createSender(String kind, String stream_id) {
435 RtpSender new_sender = nativeCreateSender(kind, stream_id);
deadbeefee524f72015-12-02 11:27:40 -0800436 if (new_sender != null) {
437 senders.add(new_sender);
438 }
439 return new_sender;
440 }
441
deadbeef4139c0f2015-10-06 12:29:25 -0700442 // Note that calling getSenders will dispose of the senders previously
443 // returned (and same goes for getReceivers).
444 public List<RtpSender> getSenders() {
445 for (RtpSender sender : senders) {
446 sender.dispose();
447 }
448 senders = nativeGetSenders();
449 return Collections.unmodifiableList(senders);
450 }
451
452 public List<RtpReceiver> getReceivers() {
453 for (RtpReceiver receiver : receivers) {
454 receiver.dispose();
455 }
456 receivers = nativeGetReceivers();
457 return Collections.unmodifiableList(receivers);
458 }
459
deadbeef82215872017-04-18 10:27:51 -0700460 // Older, non-standard implementation of getStats.
461 @Deprecated
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462 public boolean getStats(StatsObserver observer, MediaStreamTrack track) {
deadbeef82215872017-04-18 10:27:51 -0700463 return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
464 }
465
466 // Gets stats using the new stats collection API, see webrtc/api/stats/. These
467 // will replace old stats collection API when the new API has matured enough.
468 public void getStats(RTCStatsCollectorCallback callback) {
469 nativeNewGetStats(callback);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470 }
471
zsteind89b0bc2017-08-03 11:11:40 -0700472 // Limits the bandwidth allocated for all RTP streams sent by this
473 // PeerConnection. Pass null to leave a value unchanged.
474 public native boolean setBitrate(Integer min, Integer current, Integer max);
475
ivoc14d5dbe2016-07-04 07:06:55 -0700476 // Starts recording an RTC event log. Ownership of the file is transfered to
477 // the native code. If an RTC event log is already being recorded, it will be
478 // stopped and a new one will start using the provided file. Logging will
479 // continue until the stopRtcEventLog function is called. The max_size_bytes
480 // argument is ignored, it is added for future use.
ivoc0c6f0f62016-07-06 04:34:23 -0700481 public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
482 return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
ivoc14d5dbe2016-07-04 07:06:55 -0700483 }
484
485 // Stops recording an RTC event log. If no RTC event log is currently being
486 // recorded, this call will have no effect.
487 public void stopRtcEventLog() {
ivoc0c6f0f62016-07-06 04:34:23 -0700488 nativeStopRtcEventLog();
ivoc14d5dbe2016-07-04 07:06:55 -0700489 }
490
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491 // TODO(fischman): add support for DTMF-related methods once that API
492 // stabilizes.
493 public native SignalingState signalingState();
494
495 public native IceConnectionState iceConnectionState();
496
497 public native IceGatheringState iceGatheringState();
498
499 public native void close();
500
deadbeef43697f62017-09-12 10:52:14 -0700501 /**
502 * Free native resources associated with this PeerConnection instance.
503 * <p>
504 * This method removes a reference count from the C++ PeerConnection object,
505 * which should result in it being destroyed. It also calls equivalent
506 * "dispose" methods on the Java objects attached to this PeerConnection
507 * (streams, senders, receivers), such that their associated C++ objects
508 * will also be destroyed.
509 * <p>
510 * Note that this method cannot be safely called from an observer callback
511 * (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for
512 * example, destroy the PeerConnection after an "ICE failed" callback, you
513 * must do this asynchronously (in other words, unwind the stack first). See
514 * <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=3721">bug
515 * 3721</a> for more details.
516 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000517 public void dispose() {
518 close();
519 for (MediaStream stream : localStreams) {
fischman@webrtc.org32001ef2013-08-12 23:26:21 +0000520 nativeRemoveLocalStream(stream.nativeStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000521 stream.dispose();
522 }
523 localStreams.clear();
deadbeef4139c0f2015-10-06 12:29:25 -0700524 for (RtpSender sender : senders) {
525 sender.dispose();
526 }
527 senders.clear();
528 for (RtpReceiver receiver : receivers) {
529 receiver.dispose();
530 }
531 receivers.clear();
magjedb1c74532017-08-27 13:47:20 -0700532 JniCommon.nativeReleaseRef(nativePeerConnection);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000533 freeObserver(nativeObserver);
534 }
535
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536 private static native void freeObserver(long nativeObserver);
537
deadbeef5d0b6d82017-01-09 16:05:28 -0800538 public native boolean nativeSetConfiguration(RTCConfiguration config, long nativeObserver);
539
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000540 private native boolean nativeAddIceCandidate(
541 String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
542
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700543 private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
544
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000545 private native boolean nativeAddLocalStream(long nativeStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546
547 private native void nativeRemoveLocalStream(long nativeStream);
548
deadbeef82215872017-04-18 10:27:51 -0700549 private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
550
551 private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
deadbeef4139c0f2015-10-06 12:29:25 -0700552
deadbeefbd7d8f72015-12-18 16:58:44 -0800553 private native RtpSender nativeCreateSender(String kind, String stream_id);
deadbeefee524f72015-12-02 11:27:40 -0800554
deadbeef4139c0f2015-10-06 12:29:25 -0700555 private native List<RtpSender> nativeGetSenders();
556
557 private native List<RtpReceiver> nativeGetReceivers();
ivoc14d5dbe2016-07-04 07:06:55 -0700558
sakalb6760f92016-09-29 04:12:44 -0700559 private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
ivoc14d5dbe2016-07-04 07:06:55 -0700560
ivoc0c6f0f62016-07-06 04:34:23 -0700561 private native void nativeStopRtcEventLog();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562}