1 /* 2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * 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. 9 */ 10 11 package org.webrtc; 12 13 import android.support.annotation.Nullable; 14 import java.util.ArrayList; 15 import java.util.Arrays; 16 import java.util.Collections; 17 import java.util.HashMap; 18 import java.util.List; 19 import java.util.Map; 20 import org.webrtc.CandidatePairChangeEvent; 21 import org.webrtc.DataChannel; 22 import org.webrtc.MediaStreamTrack; 23 import org.webrtc.RtpTransceiver; 24 25 /** 26 * Java-land version of the PeerConnection APIs; wraps the C++ API 27 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the 28 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and 29 * http://www.w3.org/TR/mediacapture-streams/ 30 */ 31 public class PeerConnection { 32 /** Tracks PeerConnectionInterface::IceGatheringState */ 33 public enum IceGatheringState { 34 NEW, 35 GATHERING, 36 COMPLETE; 37 38 @CalledByNative("IceGatheringState") fromNativeIndex(int nativeIndex)39 static IceGatheringState fromNativeIndex(int nativeIndex) { 40 return values()[nativeIndex]; 41 } 42 } 43 44 /** Tracks PeerConnectionInterface::IceConnectionState */ 45 public enum IceConnectionState { 46 NEW, 47 CHECKING, 48 CONNECTED, 49 COMPLETED, 50 FAILED, 51 DISCONNECTED, 52 CLOSED; 53 54 @CalledByNative("IceConnectionState") fromNativeIndex(int nativeIndex)55 static IceConnectionState fromNativeIndex(int nativeIndex) { 56 return values()[nativeIndex]; 57 } 58 } 59 60 /** Tracks PeerConnectionInterface::PeerConnectionState */ 61 public enum PeerConnectionState { 62 NEW, 63 CONNECTING, 64 CONNECTED, 65 DISCONNECTED, 66 FAILED, 67 CLOSED; 68 69 @CalledByNative("PeerConnectionState") fromNativeIndex(int nativeIndex)70 static PeerConnectionState fromNativeIndex(int nativeIndex) { 71 return values()[nativeIndex]; 72 } 73 } 74 75 /** Tracks PeerConnectionInterface::TlsCertPolicy */ 76 public enum TlsCertPolicy { 77 TLS_CERT_POLICY_SECURE, 78 TLS_CERT_POLICY_INSECURE_NO_CHECK, 79 } 80 81 /** Tracks PeerConnectionInterface::SignalingState */ 82 public enum SignalingState { 83 STABLE, 84 HAVE_LOCAL_OFFER, 85 HAVE_LOCAL_PRANSWER, 86 HAVE_REMOTE_OFFER, 87 HAVE_REMOTE_PRANSWER, 88 CLOSED; 89 90 @CalledByNative("SignalingState") fromNativeIndex(int nativeIndex)91 static SignalingState fromNativeIndex(int nativeIndex) { 92 return values()[nativeIndex]; 93 } 94 } 95 96 /** Java version of PeerConnectionObserver. */ 97 public static interface Observer { 98 /** Triggered when the SignalingState changes. */ onSignalingChange(SignalingState newState)99 @CalledByNative("Observer") void onSignalingChange(SignalingState newState); 100 101 /** Triggered when the IceConnectionState changes. */ onIceConnectionChange(IceConnectionState newState)102 @CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState); 103 104 /* Triggered when the standard-compliant state transition of IceConnectionState happens. */ 105 @CalledByNative("Observer") onStandardizedIceConnectionChange(IceConnectionState newState)106 default void onStandardizedIceConnectionChange(IceConnectionState newState) {} 107 108 /** Triggered when the PeerConnectionState changes. */ 109 @CalledByNative("Observer") onConnectionChange(PeerConnectionState newState)110 default void onConnectionChange(PeerConnectionState newState) {} 111 112 /** Triggered when the ICE connection receiving status changes. */ onIceConnectionReceivingChange(boolean receiving)113 @CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving); 114 115 /** Triggered when the IceGatheringState changes. */ onIceGatheringChange(IceGatheringState newState)116 @CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState); 117 118 /** Triggered when a new ICE candidate has been found. */ onIceCandidate(IceCandidate candidate)119 @CalledByNative("Observer") void onIceCandidate(IceCandidate candidate); 120 121 /** Triggered when some ICE candidates have been removed. */ onIceCandidatesRemoved(IceCandidate[] candidates)122 @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates); 123 124 /** Triggered when the ICE candidate pair is changed. */ 125 @CalledByNative("Observer") onSelectedCandidatePairChanged(CandidatePairChangeEvent event)126 default void onSelectedCandidatePairChanged(CandidatePairChangeEvent event) {} 127 128 /** Triggered when media is received on a new stream from remote peer. */ onAddStream(MediaStream stream)129 @CalledByNative("Observer") void onAddStream(MediaStream stream); 130 131 /** Triggered when a remote peer close a stream. */ onRemoveStream(MediaStream stream)132 @CalledByNative("Observer") void onRemoveStream(MediaStream stream); 133 134 /** Triggered when a remote peer opens a DataChannel. */ onDataChannel(DataChannel dataChannel)135 @CalledByNative("Observer") void onDataChannel(DataChannel dataChannel); 136 137 /** Triggered when renegotiation is necessary. */ onRenegotiationNeeded()138 @CalledByNative("Observer") void onRenegotiationNeeded(); 139 140 /** 141 * Triggered when a new track is signaled by the remote peer, as a result of 142 * setRemoteDescription. 143 */ onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams)144 @CalledByNative("Observer") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams); 145 146 /** 147 * Triggered when the signaling from SetRemoteDescription indicates that a transceiver 148 * will be receiving media from a remote endpoint. This is only called if UNIFIED_PLAN 149 * semantics are specified. The transceiver will be disposed automatically. 150 */ onTrack(RtpTransceiver transceiver)151 @CalledByNative("Observer") default void onTrack(RtpTransceiver transceiver){}; 152 } 153 154 /** Java version of PeerConnectionInterface.IceServer. */ 155 public static class IceServer { 156 // List of URIs associated with this server. Valid formats are described 157 // in RFC7064 and RFC7065, and more may be added in the future. The "host" 158 // part of the URI may contain either an IP address or a hostname. 159 @Deprecated public final String uri; 160 public final List<String> urls; 161 public final String username; 162 public final String password; 163 public final TlsCertPolicy tlsCertPolicy; 164 165 // If the URIs in |urls| only contain IP addresses, this field can be used 166 // to indicate the hostname, which may be necessary for TLS (using the SNI 167 // extension). If |urls| itself contains the hostname, this isn't 168 // necessary. 169 public final String hostname; 170 171 // List of protocols to be used in the TLS ALPN extension. 172 public final List<String> tlsAlpnProtocols; 173 174 // List of elliptic curves to be used in the TLS elliptic curves extension. 175 // Only curve names supported by OpenSSL should be used (eg. "P-256","X25519"). 176 public final List<String> tlsEllipticCurves; 177 178 /** Convenience constructor for STUN servers. */ 179 @Deprecated IceServer(String uri)180 public IceServer(String uri) { 181 this(uri, "", ""); 182 } 183 184 @Deprecated IceServer(String uri, String username, String password)185 public IceServer(String uri, String username, String password) { 186 this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE); 187 } 188 189 @Deprecated IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy)190 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) { 191 this(uri, username, password, tlsCertPolicy, ""); 192 } 193 194 @Deprecated IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy, String hostname)195 public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy, 196 String hostname) { 197 this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null, 198 null); 199 } 200 IceServer(String uri, List<String> urls, String username, String password, TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols, List<String> tlsEllipticCurves)201 private IceServer(String uri, List<String> urls, String username, String password, 202 TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols, 203 List<String> tlsEllipticCurves) { 204 if (uri == null || urls == null || urls.isEmpty()) { 205 throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()"); 206 } 207 for (String it : urls) { 208 if (it == null) { 209 throw new IllegalArgumentException("urls element is null: " + urls); 210 } 211 } 212 if (username == null) { 213 throw new IllegalArgumentException("username == null"); 214 } 215 if (password == null) { 216 throw new IllegalArgumentException("password == null"); 217 } 218 if (hostname == null) { 219 throw new IllegalArgumentException("hostname == null"); 220 } 221 this.uri = uri; 222 this.urls = urls; 223 this.username = username; 224 this.password = password; 225 this.tlsCertPolicy = tlsCertPolicy; 226 this.hostname = hostname; 227 this.tlsAlpnProtocols = tlsAlpnProtocols; 228 this.tlsEllipticCurves = tlsEllipticCurves; 229 } 230 231 @Override toString()232 public String toString() { 233 return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname 234 + "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]"; 235 } 236 237 @Override equals(@ullable Object obj)238 public boolean equals(@Nullable Object obj) { 239 if (obj == null) { 240 return false; 241 } 242 if (obj == this) { 243 return true; 244 } 245 if (!(obj instanceof IceServer)) { 246 return false; 247 } 248 IceServer other = (IceServer) obj; 249 return (uri.equals(other.uri) && urls.equals(other.urls) && username.equals(other.username) 250 && password.equals(other.password) && tlsCertPolicy.equals(other.tlsCertPolicy) 251 && hostname.equals(other.hostname) && tlsAlpnProtocols.equals(other.tlsAlpnProtocols) 252 && tlsEllipticCurves.equals(other.tlsEllipticCurves)); 253 } 254 255 @Override hashCode()256 public int hashCode() { 257 Object[] values = {uri, urls, username, password, tlsCertPolicy, hostname, tlsAlpnProtocols, 258 tlsEllipticCurves}; 259 return Arrays.hashCode(values); 260 } 261 builder(String uri)262 public static Builder builder(String uri) { 263 return new Builder(Collections.singletonList(uri)); 264 } 265 builder(List<String> urls)266 public static Builder builder(List<String> urls) { 267 return new Builder(urls); 268 } 269 270 public static class Builder { 271 @Nullable private final List<String> urls; 272 private String username = ""; 273 private String password = ""; 274 private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE; 275 private String hostname = ""; 276 private List<String> tlsAlpnProtocols; 277 private List<String> tlsEllipticCurves; 278 Builder(List<String> urls)279 private Builder(List<String> urls) { 280 if (urls == null || urls.isEmpty()) { 281 throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls); 282 } 283 this.urls = urls; 284 } 285 setUsername(String username)286 public Builder setUsername(String username) { 287 this.username = username; 288 return this; 289 } 290 setPassword(String password)291 public Builder setPassword(String password) { 292 this.password = password; 293 return this; 294 } 295 setTlsCertPolicy(TlsCertPolicy tlsCertPolicy)296 public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) { 297 this.tlsCertPolicy = tlsCertPolicy; 298 return this; 299 } 300 setHostname(String hostname)301 public Builder setHostname(String hostname) { 302 this.hostname = hostname; 303 return this; 304 } 305 setTlsAlpnProtocols(List<String> tlsAlpnProtocols)306 public Builder setTlsAlpnProtocols(List<String> tlsAlpnProtocols) { 307 this.tlsAlpnProtocols = tlsAlpnProtocols; 308 return this; 309 } 310 setTlsEllipticCurves(List<String> tlsEllipticCurves)311 public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) { 312 this.tlsEllipticCurves = tlsEllipticCurves; 313 return this; 314 } 315 createIceServer()316 public IceServer createIceServer() { 317 return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname, 318 tlsAlpnProtocols, tlsEllipticCurves); 319 } 320 } 321 322 @Nullable 323 @CalledByNative("IceServer") getUrls()324 List<String> getUrls() { 325 return urls; 326 } 327 328 @Nullable 329 @CalledByNative("IceServer") getUsername()330 String getUsername() { 331 return username; 332 } 333 334 @Nullable 335 @CalledByNative("IceServer") getPassword()336 String getPassword() { 337 return password; 338 } 339 340 @CalledByNative("IceServer") getTlsCertPolicy()341 TlsCertPolicy getTlsCertPolicy() { 342 return tlsCertPolicy; 343 } 344 345 @Nullable 346 @CalledByNative("IceServer") getHostname()347 String getHostname() { 348 return hostname; 349 } 350 351 @CalledByNative("IceServer") getTlsAlpnProtocols()352 List<String> getTlsAlpnProtocols() { 353 return tlsAlpnProtocols; 354 } 355 356 @CalledByNative("IceServer") getTlsEllipticCurves()357 List<String> getTlsEllipticCurves() { 358 return tlsEllipticCurves; 359 } 360 } 361 362 /** Java version of PeerConnectionInterface.IceTransportsType */ 363 public enum IceTransportsType { NONE, RELAY, NOHOST, ALL } 364 365 /** Java version of PeerConnectionInterface.BundlePolicy */ 366 public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT } 367 368 /** Java version of PeerConnectionInterface.RtcpMuxPolicy */ 369 public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE } 370 371 /** Java version of PeerConnectionInterface.TcpCandidatePolicy */ 372 public enum TcpCandidatePolicy { ENABLED, DISABLED } 373 374 /** Java version of PeerConnectionInterface.CandidateNetworkPolicy */ 375 public enum CandidateNetworkPolicy { ALL, LOW_COST } 376 377 // Keep in sync with webrtc/rtc_base/network_constants.h. 378 public enum AdapterType { 379 UNKNOWN(0), 380 ETHERNET(1 << 0), 381 WIFI(1 << 1), 382 CELLULAR(1 << 2), 383 VPN(1 << 3), 384 LOOPBACK(1 << 4), 385 ADAPTER_TYPE_ANY(1 << 5), 386 CELLULAR_2G(1 << 6), 387 CELLULAR_3G(1 << 7), 388 CELLULAR_4G(1 << 8), 389 CELLULAR_5G(1 << 9); 390 391 public final Integer bitMask; AdapterType(Integer bitMask)392 private AdapterType(Integer bitMask) { 393 this.bitMask = bitMask; 394 } 395 private static final Map<Integer, AdapterType> BY_BITMASK = new HashMap<>(); 396 static { 397 for (AdapterType t : values()) { BY_BITMASK.put(t.bitMask, t)398 BY_BITMASK.put(t.bitMask, t); 399 } 400 } 401 402 @Nullable 403 @CalledByNative("AdapterType") fromNativeIndex(int nativeIndex)404 static AdapterType fromNativeIndex(int nativeIndex) { 405 return BY_BITMASK.get(nativeIndex); 406 } 407 } 408 409 /** Java version of rtc::KeyType */ 410 public enum KeyType { RSA, ECDSA } 411 412 /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */ 413 public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY } 414 415 /** Java version of webrtc::PortPrunePolicy */ 416 public enum PortPrunePolicy { 417 NO_PRUNE, // Do not prune turn port. 418 PRUNE_BASED_ON_PRIORITY, // Prune turn port based the priority on the same network 419 KEEP_FIRST_READY // Keep the first ready port and prune the rest on the same network. 420 } 421 422 /** 423 * Java version of webrtc::SdpSemantics. 424 * 425 * Configure the SDP semantics used by this PeerConnection. Note that the 426 * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The 427 * RtpTransceiver API is only available with UNIFIED_PLAN semantics. 428 * 429 * <p>PLAN_B will cause PeerConnection to create offers and answers with at 430 * most one audio and one video m= section with multiple RtpSenders and 431 * RtpReceivers specified as multiple a=ssrc lines within the section. This 432 * will also cause PeerConnection to ignore all but the first m= section of 433 * the same media type. 434 * 435 * <p>UNIFIED_PLAN will cause PeerConnection to create offers and answers with 436 * multiple m= sections where each m= section maps to one RtpSender and one 437 * RtpReceiver (an RtpTransceiver), either both audio or both video. This 438 * will also cause PeerConnection to ignore all but the first a=ssrc lines 439 * that form a Plan B stream. 440 * 441 * <p>For users who wish to send multiple audio/video streams and need to stay 442 * interoperable with legacy WebRTC implementations, specify PLAN_B. 443 * 444 * <p>For users who wish to send multiple audio/video streams and/or wish to 445 * use the new RtpTransceiver API, specify UNIFIED_PLAN. 446 */ 447 public enum SdpSemantics { PLAN_B, UNIFIED_PLAN } 448 449 /** Java version of PeerConnectionInterface.RTCConfiguration */ 450 // TODO(qingsi): Resolve the naming inconsistency of fields with/without units. 451 public static class RTCConfiguration { 452 public IceTransportsType iceTransportsType; 453 public List<IceServer> iceServers; 454 public BundlePolicy bundlePolicy; 455 @Nullable public RtcCertificatePem certificate; 456 public RtcpMuxPolicy rtcpMuxPolicy; 457 public TcpCandidatePolicy tcpCandidatePolicy; 458 public CandidateNetworkPolicy candidateNetworkPolicy; 459 public int audioJitterBufferMaxPackets; 460 public boolean audioJitterBufferFastAccelerate; 461 public int iceConnectionReceivingTimeout; 462 public int iceBackupCandidatePairPingInterval; 463 public KeyType keyType; 464 public ContinualGatheringPolicy continualGatheringPolicy; 465 public int iceCandidatePoolSize; 466 @Deprecated // by the turnPortPrunePolicy. See bugs.webrtc.org/11026 467 public boolean pruneTurnPorts; 468 public PortPrunePolicy turnPortPrunePolicy; 469 public boolean presumeWritableWhenFullyRelayed; 470 public boolean surfaceIceCandidatesOnIceTransportTypeChanged; 471 // The following fields define intervals in milliseconds at which ICE 472 // connectivity checks are sent. 473 // 474 // We consider ICE is "strongly connected" for an agent when there is at 475 // least one candidate pair that currently succeeds in connectivity check 476 // from its direction i.e. sending a ping and receives a ping response, AND 477 // all candidate pairs have sent a minimum number of pings for connectivity 478 // (this number is implementation-specific). Otherwise, ICE is considered in 479 // "weak connectivity". 480 // 481 // Note that the above notion of strong and weak connectivity is not defined 482 // in RFC 5245, and they apply to our current ICE implementation only. 483 // 484 // 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to 485 // ALL candidate pairs when ICE is strongly connected, 486 // 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL 487 // pairs when ICE is weakly connected, and 488 // 3) iceCheckMinInterval defines the minimal interval (equivalently the 489 // maximum rate) that overrides the above two intervals when either of them 490 // is less. 491 @Nullable public Integer iceCheckIntervalStrongConnectivityMs; 492 @Nullable public Integer iceCheckIntervalWeakConnectivityMs; 493 @Nullable public Integer iceCheckMinInterval; 494 // The time period in milliseconds for which a candidate pair must wait for response to 495 // connectivitiy checks before it becomes unwritable. 496 @Nullable public Integer iceUnwritableTimeMs; 497 // The minimum number of connectivity checks that a candidate pair must sent without receiving 498 // response before it becomes unwritable. 499 @Nullable public Integer iceUnwritableMinChecks; 500 // The interval in milliseconds at which STUN candidates will resend STUN binding requests 501 // to keep NAT bindings open. 502 // The default value in the implementation is used if this field is null. 503 @Nullable public Integer stunCandidateKeepaliveIntervalMs; 504 public boolean disableIPv6OnWifi; 505 // By default, PeerConnection will use a limited number of IPv6 network 506 // interfaces, in order to avoid too many ICE candidate pairs being created 507 // and delaying ICE completion. 508 // 509 // Can be set to Integer.MAX_VALUE to effectively disable the limit. 510 public int maxIPv6Networks; 511 512 // These values will be overridden by MediaStream constraints if deprecated constraints-based 513 // create peerconnection interface is used. 514 public boolean disableIpv6; 515 public boolean enableDscp; 516 public boolean enableCpuOveruseDetection; 517 public boolean enableRtpDataChannel; 518 public boolean suspendBelowMinBitrate; 519 @Nullable public Integer screencastMinBitrate; 520 @Nullable public Boolean combinedAudioVideoBwe; 521 @Nullable public Boolean enableDtlsSrtp; 522 // Use "Unknown" to represent no preference of adapter types, not the 523 // preference of adapters of unknown types. 524 public AdapterType networkPreference; 525 public SdpSemantics sdpSemantics; 526 527 // This is an optional wrapper for the C++ webrtc::TurnCustomizer. 528 @Nullable public TurnCustomizer turnCustomizer; 529 530 // Actively reset the SRTP parameters whenever the DTLS transports underneath are reset for 531 // every offer/answer negotiation.This is only intended to be a workaround for crbug.com/835958 532 public boolean activeResetSrtpParams; 533 534 // Whether this client is allowed to switch encoding codec mid-stream. This is a workaround for 535 // a WebRTC bug where the receiver could get confussed if a codec switch happened mid-call. 536 // Null indicates no change to currently configured value. 537 @Nullable public Boolean allowCodecSwitching; 538 539 /** 540 * Defines advanced optional cryptographic settings related to SRTP and 541 * frame encryption for native WebRTC. Setting this will overwrite any 542 * options set through the PeerConnectionFactory (which is deprecated). 543 */ 544 @Nullable public CryptoOptions cryptoOptions; 545 546 /** 547 * An optional string that if set will be attached to the 548 * TURN_ALLOCATE_REQUEST which can be used to correlate client 549 * logs with backend logs 550 */ 551 @Nullable public String turnLoggingId; 552 553 // TODO(deadbeef): Instead of duplicating the defaults here, we should do 554 // something to pick up the defaults from C++. The Objective-C equivalent 555 // of RTCConfiguration does that. RTCConfiguration(List<IceServer> iceServers)556 public RTCConfiguration(List<IceServer> iceServers) { 557 iceTransportsType = IceTransportsType.ALL; 558 bundlePolicy = BundlePolicy.BALANCED; 559 rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE; 560 tcpCandidatePolicy = TcpCandidatePolicy.ENABLED; 561 candidateNetworkPolicy = CandidateNetworkPolicy.ALL; 562 this.iceServers = iceServers; 563 audioJitterBufferMaxPackets = 50; 564 audioJitterBufferFastAccelerate = false; 565 iceConnectionReceivingTimeout = -1; 566 iceBackupCandidatePairPingInterval = -1; 567 keyType = KeyType.ECDSA; 568 continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE; 569 iceCandidatePoolSize = 0; 570 pruneTurnPorts = false; 571 turnPortPrunePolicy = PortPrunePolicy.NO_PRUNE; 572 presumeWritableWhenFullyRelayed = false; 573 surfaceIceCandidatesOnIceTransportTypeChanged = false; 574 iceCheckIntervalStrongConnectivityMs = null; 575 iceCheckIntervalWeakConnectivityMs = null; 576 iceCheckMinInterval = null; 577 iceUnwritableTimeMs = null; 578 iceUnwritableMinChecks = null; 579 stunCandidateKeepaliveIntervalMs = null; 580 disableIPv6OnWifi = false; 581 maxIPv6Networks = 5; 582 disableIpv6 = false; 583 enableDscp = false; 584 enableCpuOveruseDetection = true; 585 enableRtpDataChannel = false; 586 suspendBelowMinBitrate = false; 587 screencastMinBitrate = null; 588 combinedAudioVideoBwe = null; 589 enableDtlsSrtp = null; 590 networkPreference = AdapterType.UNKNOWN; 591 sdpSemantics = SdpSemantics.PLAN_B; 592 activeResetSrtpParams = false; 593 cryptoOptions = null; 594 turnLoggingId = null; 595 allowCodecSwitching = null; 596 } 597 598 @CalledByNative("RTCConfiguration") getIceTransportsType()599 IceTransportsType getIceTransportsType() { 600 return iceTransportsType; 601 } 602 603 @CalledByNative("RTCConfiguration") getIceServers()604 List<IceServer> getIceServers() { 605 return iceServers; 606 } 607 608 @CalledByNative("RTCConfiguration") getBundlePolicy()609 BundlePolicy getBundlePolicy() { 610 return bundlePolicy; 611 } 612 613 @CalledByNative("RTCConfiguration") getTurnPortPrunePolicy()614 PortPrunePolicy getTurnPortPrunePolicy() { 615 return turnPortPrunePolicy; 616 } 617 618 @Nullable 619 @CalledByNative("RTCConfiguration") getCertificate()620 RtcCertificatePem getCertificate() { 621 return certificate; 622 } 623 624 @CalledByNative("RTCConfiguration") getRtcpMuxPolicy()625 RtcpMuxPolicy getRtcpMuxPolicy() { 626 return rtcpMuxPolicy; 627 } 628 629 @CalledByNative("RTCConfiguration") getTcpCandidatePolicy()630 TcpCandidatePolicy getTcpCandidatePolicy() { 631 return tcpCandidatePolicy; 632 } 633 634 @CalledByNative("RTCConfiguration") getCandidateNetworkPolicy()635 CandidateNetworkPolicy getCandidateNetworkPolicy() { 636 return candidateNetworkPolicy; 637 } 638 639 @CalledByNative("RTCConfiguration") getAudioJitterBufferMaxPackets()640 int getAudioJitterBufferMaxPackets() { 641 return audioJitterBufferMaxPackets; 642 } 643 644 @CalledByNative("RTCConfiguration") getAudioJitterBufferFastAccelerate()645 boolean getAudioJitterBufferFastAccelerate() { 646 return audioJitterBufferFastAccelerate; 647 } 648 649 @CalledByNative("RTCConfiguration") getIceConnectionReceivingTimeout()650 int getIceConnectionReceivingTimeout() { 651 return iceConnectionReceivingTimeout; 652 } 653 654 @CalledByNative("RTCConfiguration") getIceBackupCandidatePairPingInterval()655 int getIceBackupCandidatePairPingInterval() { 656 return iceBackupCandidatePairPingInterval; 657 } 658 659 @CalledByNative("RTCConfiguration") getKeyType()660 KeyType getKeyType() { 661 return keyType; 662 } 663 664 @CalledByNative("RTCConfiguration") getContinualGatheringPolicy()665 ContinualGatheringPolicy getContinualGatheringPolicy() { 666 return continualGatheringPolicy; 667 } 668 669 @CalledByNative("RTCConfiguration") getIceCandidatePoolSize()670 int getIceCandidatePoolSize() { 671 return iceCandidatePoolSize; 672 } 673 674 @CalledByNative("RTCConfiguration") getPruneTurnPorts()675 boolean getPruneTurnPorts() { 676 return pruneTurnPorts; 677 } 678 679 @CalledByNative("RTCConfiguration") getPresumeWritableWhenFullyRelayed()680 boolean getPresumeWritableWhenFullyRelayed() { 681 return presumeWritableWhenFullyRelayed; 682 } 683 684 @CalledByNative("RTCConfiguration") getSurfaceIceCandidatesOnIceTransportTypeChanged()685 boolean getSurfaceIceCandidatesOnIceTransportTypeChanged() { 686 return surfaceIceCandidatesOnIceTransportTypeChanged; 687 } 688 689 @Nullable 690 @CalledByNative("RTCConfiguration") getIceCheckIntervalStrongConnectivity()691 Integer getIceCheckIntervalStrongConnectivity() { 692 return iceCheckIntervalStrongConnectivityMs; 693 } 694 695 @Nullable 696 @CalledByNative("RTCConfiguration") getIceCheckIntervalWeakConnectivity()697 Integer getIceCheckIntervalWeakConnectivity() { 698 return iceCheckIntervalWeakConnectivityMs; 699 } 700 701 @Nullable 702 @CalledByNative("RTCConfiguration") getIceCheckMinInterval()703 Integer getIceCheckMinInterval() { 704 return iceCheckMinInterval; 705 } 706 707 @Nullable 708 @CalledByNative("RTCConfiguration") getIceUnwritableTimeout()709 Integer getIceUnwritableTimeout() { 710 return iceUnwritableTimeMs; 711 } 712 713 @Nullable 714 @CalledByNative("RTCConfiguration") getIceUnwritableMinChecks()715 Integer getIceUnwritableMinChecks() { 716 return iceUnwritableMinChecks; 717 } 718 719 @Nullable 720 @CalledByNative("RTCConfiguration") getStunCandidateKeepaliveInterval()721 Integer getStunCandidateKeepaliveInterval() { 722 return stunCandidateKeepaliveIntervalMs; 723 } 724 725 @CalledByNative("RTCConfiguration") getDisableIPv6OnWifi()726 boolean getDisableIPv6OnWifi() { 727 return disableIPv6OnWifi; 728 } 729 730 @CalledByNative("RTCConfiguration") getMaxIPv6Networks()731 int getMaxIPv6Networks() { 732 return maxIPv6Networks; 733 } 734 735 @Nullable 736 @CalledByNative("RTCConfiguration") getTurnCustomizer()737 TurnCustomizer getTurnCustomizer() { 738 return turnCustomizer; 739 } 740 741 @CalledByNative("RTCConfiguration") getDisableIpv6()742 boolean getDisableIpv6() { 743 return disableIpv6; 744 } 745 746 @CalledByNative("RTCConfiguration") getEnableDscp()747 boolean getEnableDscp() { 748 return enableDscp; 749 } 750 751 @CalledByNative("RTCConfiguration") getEnableCpuOveruseDetection()752 boolean getEnableCpuOveruseDetection() { 753 return enableCpuOveruseDetection; 754 } 755 756 @CalledByNative("RTCConfiguration") getEnableRtpDataChannel()757 boolean getEnableRtpDataChannel() { 758 return enableRtpDataChannel; 759 } 760 761 @CalledByNative("RTCConfiguration") getSuspendBelowMinBitrate()762 boolean getSuspendBelowMinBitrate() { 763 return suspendBelowMinBitrate; 764 } 765 766 @Nullable 767 @CalledByNative("RTCConfiguration") getScreencastMinBitrate()768 Integer getScreencastMinBitrate() { 769 return screencastMinBitrate; 770 } 771 772 @Nullable 773 @CalledByNative("RTCConfiguration") getCombinedAudioVideoBwe()774 Boolean getCombinedAudioVideoBwe() { 775 return combinedAudioVideoBwe; 776 } 777 778 @Nullable 779 @CalledByNative("RTCConfiguration") getEnableDtlsSrtp()780 Boolean getEnableDtlsSrtp() { 781 return enableDtlsSrtp; 782 } 783 784 @CalledByNative("RTCConfiguration") getNetworkPreference()785 AdapterType getNetworkPreference() { 786 return networkPreference; 787 } 788 789 @CalledByNative("RTCConfiguration") getSdpSemantics()790 SdpSemantics getSdpSemantics() { 791 return sdpSemantics; 792 } 793 794 @CalledByNative("RTCConfiguration") getActiveResetSrtpParams()795 boolean getActiveResetSrtpParams() { 796 return activeResetSrtpParams; 797 } 798 799 @Nullable 800 @CalledByNative("RTCConfiguration") getAllowCodecSwitching()801 Boolean getAllowCodecSwitching() { 802 return allowCodecSwitching; 803 } 804 805 @Nullable 806 @CalledByNative("RTCConfiguration") getCryptoOptions()807 CryptoOptions getCryptoOptions() { 808 return cryptoOptions; 809 } 810 811 @Nullable 812 @CalledByNative("RTCConfiguration") getTurnLoggingId()813 String getTurnLoggingId() { 814 return turnLoggingId; 815 } 816 }; 817 818 private final List<MediaStream> localStreams = new ArrayList<>(); 819 private final long nativePeerConnection; 820 private List<RtpSender> senders = new ArrayList<>(); 821 private List<RtpReceiver> receivers = new ArrayList<>(); 822 private List<RtpTransceiver> transceivers = new ArrayList<>(); 823 824 /** 825 * Wraps a PeerConnection created by the factory. Can be used by clients that want to implement 826 * their PeerConnection creation in JNI. 827 */ PeerConnection(NativePeerConnectionFactory factory)828 public PeerConnection(NativePeerConnectionFactory factory) { 829 this(factory.createNativePeerConnection()); 830 } 831 PeerConnection(long nativePeerConnection)832 PeerConnection(long nativePeerConnection) { 833 this.nativePeerConnection = nativePeerConnection; 834 } 835 836 // JsepInterface. getLocalDescription()837 public SessionDescription getLocalDescription() { 838 return nativeGetLocalDescription(); 839 } 840 getRemoteDescription()841 public SessionDescription getRemoteDescription() { 842 return nativeGetRemoteDescription(); 843 } 844 getCertificate()845 public RtcCertificatePem getCertificate() { 846 return nativeGetCertificate(); 847 } 848 createDataChannel(String label, DataChannel.Init init)849 public DataChannel createDataChannel(String label, DataChannel.Init init) { 850 return nativeCreateDataChannel(label, init); 851 } 852 createOffer(SdpObserver observer, MediaConstraints constraints)853 public void createOffer(SdpObserver observer, MediaConstraints constraints) { 854 nativeCreateOffer(observer, constraints); 855 } 856 createAnswer(SdpObserver observer, MediaConstraints constraints)857 public void createAnswer(SdpObserver observer, MediaConstraints constraints) { 858 nativeCreateAnswer(observer, constraints); 859 } 860 setLocalDescription(SdpObserver observer, SessionDescription sdp)861 public void setLocalDescription(SdpObserver observer, SessionDescription sdp) { 862 nativeSetLocalDescription(observer, sdp); 863 } 864 setRemoteDescription(SdpObserver observer, SessionDescription sdp)865 public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) { 866 nativeSetRemoteDescription(observer, sdp); 867 } 868 869 /** 870 * Enables/disables playout of received audio streams. Enabled by default. 871 * 872 * Note that even if playout is enabled, streams will only be played out if 873 * the appropriate SDP is also applied. The main purpose of this API is to 874 * be able to control the exact time when audio playout starts. 875 */ setAudioPlayout(boolean playout)876 public void setAudioPlayout(boolean playout) { 877 nativeSetAudioPlayout(playout); 878 } 879 880 /** 881 * Enables/disables recording of transmitted audio streams. Enabled by default. 882 * 883 * Note that even if recording is enabled, streams will only be recorded if 884 * the appropriate SDP is also applied. The main purpose of this API is to 885 * be able to control the exact time when audio recording starts. 886 */ setAudioRecording(boolean recording)887 public void setAudioRecording(boolean recording) { 888 nativeSetAudioRecording(recording); 889 } 890 setConfiguration(RTCConfiguration config)891 public boolean setConfiguration(RTCConfiguration config) { 892 return nativeSetConfiguration(config); 893 } 894 addIceCandidate(IceCandidate candidate)895 public boolean addIceCandidate(IceCandidate candidate) { 896 return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); 897 } 898 removeIceCandidates(final IceCandidate[] candidates)899 public boolean removeIceCandidates(final IceCandidate[] candidates) { 900 return nativeRemoveIceCandidates(candidates); 901 } 902 903 /** 904 * Adds a new MediaStream to be sent on this peer connection. 905 * Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please 906 * use addTrack instead. 907 */ addStream(MediaStream stream)908 public boolean addStream(MediaStream stream) { 909 boolean ret = nativeAddLocalStream(stream.getNativeMediaStream()); 910 if (!ret) { 911 return false; 912 } 913 localStreams.add(stream); 914 return true; 915 } 916 917 /** 918 * Removes the given media stream from this peer connection. 919 * This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use 920 * removeTrack instead. 921 */ removeStream(MediaStream stream)922 public void removeStream(MediaStream stream) { 923 nativeRemoveLocalStream(stream.getNativeMediaStream()); 924 localStreams.remove(stream); 925 } 926 927 /** 928 * Creates an RtpSender without a track. 929 * 930 * <p>This method allows an application to cause the PeerConnection to negotiate 931 * sending/receiving a specific media type, but without having a track to 932 * send yet. 933 * 934 * <p>When the application does want to begin sending a track, it can call 935 * RtpSender.setTrack, which doesn't require any additional SDP negotiation. 936 * 937 * <p>Example use: 938 * <pre> 939 * {@code 940 * audioSender = pc.createSender("audio", "stream1"); 941 * videoSender = pc.createSender("video", "stream1"); 942 * // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate 943 * // media parameters.... 944 * // Later, when the endpoint is ready to actually begin sending: 945 * audioSender.setTrack(audioTrack, false); 946 * videoSender.setTrack(videoTrack, false); 947 * } 948 * </pre> 949 * <p>Note: This corresponds most closely to "addTransceiver" in the official 950 * WebRTC API, in that it creates a sender without a track. It was 951 * implemented before addTransceiver because it provides useful 952 * functionality, and properly implementing transceivers would have required 953 * a great deal more work. 954 * 955 * <p>Note: This is only available with SdpSemantics.PLAN_B specified. Please use 956 * addTransceiver instead. 957 * 958 * @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or 959 * "video"). 960 * @param stream_id The ID of the MediaStream that this sender's track will 961 * be associated with when SDP is applied to the remote 962 * PeerConnection. If createSender is used to create an 963 * audio and video sender that should be synchronized, they 964 * should use the same stream ID. 965 * @return A new RtpSender object if successful, or null otherwise. 966 */ createSender(String kind, String stream_id)967 public RtpSender createSender(String kind, String stream_id) { 968 RtpSender newSender = nativeCreateSender(kind, stream_id); 969 if (newSender != null) { 970 senders.add(newSender); 971 } 972 return newSender; 973 } 974 975 /** 976 * Gets all RtpSenders associated with this peer connection. 977 * Note that calling getSenders will dispose of the senders previously 978 * returned. 979 */ getSenders()980 public List<RtpSender> getSenders() { 981 for (RtpSender sender : senders) { 982 sender.dispose(); 983 } 984 senders = nativeGetSenders(); 985 return Collections.unmodifiableList(senders); 986 } 987 988 /** 989 * Gets all RtpReceivers associated with this peer connection. 990 * Note that calling getReceivers will dispose of the receivers previously 991 * returned. 992 */ getReceivers()993 public List<RtpReceiver> getReceivers() { 994 for (RtpReceiver receiver : receivers) { 995 receiver.dispose(); 996 } 997 receivers = nativeGetReceivers(); 998 return Collections.unmodifiableList(receivers); 999 } 1000 1001 /** 1002 * Gets all RtpTransceivers associated with this peer connection. 1003 * Note that calling getTransceivers will dispose of the transceivers previously 1004 * returned. 1005 * Note: This is only available with SdpSemantics.UNIFIED_PLAN specified. 1006 */ getTransceivers()1007 public List<RtpTransceiver> getTransceivers() { 1008 for (RtpTransceiver transceiver : transceivers) { 1009 transceiver.dispose(); 1010 } 1011 transceivers = nativeGetTransceivers(); 1012 return Collections.unmodifiableList(transceivers); 1013 } 1014 1015 /** 1016 * Adds a new media stream track to be sent on this peer connection, and returns 1017 * the newly created RtpSender. If streamIds are specified, the RtpSender will 1018 * be associated with the streams specified in the streamIds list. 1019 * 1020 * @throws IllegalStateException if an error accors in C++ addTrack. 1021 * An error can occur if: 1022 * - A sender already exists for the track. 1023 * - The peer connection is closed. 1024 */ addTrack(MediaStreamTrack track)1025 public RtpSender addTrack(MediaStreamTrack track) { 1026 return addTrack(track, Collections.emptyList()); 1027 } 1028 addTrack(MediaStreamTrack track, List<String> streamIds)1029 public RtpSender addTrack(MediaStreamTrack track, List<String> streamIds) { 1030 if (track == null || streamIds == null) { 1031 throw new NullPointerException("No MediaStreamTrack specified in addTrack."); 1032 } 1033 RtpSender newSender = nativeAddTrack(track.getNativeMediaStreamTrack(), streamIds); 1034 if (newSender == null) { 1035 throw new IllegalStateException("C++ addTrack failed."); 1036 } 1037 senders.add(newSender); 1038 return newSender; 1039 } 1040 1041 /** 1042 * Stops sending media from sender. The sender will still appear in getSenders. Future 1043 * calls to createOffer will mark the m section for the corresponding transceiver as 1044 * receive only or inactive, as defined in JSEP. Returns true on success. 1045 */ removeTrack(RtpSender sender)1046 public boolean removeTrack(RtpSender sender) { 1047 if (sender == null) { 1048 throw new NullPointerException("No RtpSender specified for removeTrack."); 1049 } 1050 return nativeRemoveTrack(sender.getNativeRtpSender()); 1051 } 1052 1053 /** 1054 * Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a 1055 * transceiver will cause future calls to CreateOffer to add a media description 1056 * for the corresponding transceiver. 1057 * 1058 * <p>The initial value of |mid| in the returned transceiver is null. Setting a 1059 * new session description may change it to a non-null value. 1060 * 1061 * <p>https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver 1062 * 1063 * <p>If a MediaStreamTrack is specified then a transceiver will be added with a 1064 * sender set to transmit the given track. The kind 1065 * of the transceiver (and sender/receiver) will be derived from the kind of 1066 * the track. 1067 * 1068 * <p>If MediaType is specified then a transceiver will be added based upon that type. 1069 * This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO. 1070 * 1071 * <p>Optionally, an RtpTransceiverInit structure can be specified to configure 1072 * the transceiver from construction. If not specified, the transceiver will 1073 * default to having a direction of kSendRecv and not be part of any streams. 1074 * 1075 * <p>Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified. 1076 * @throws IllegalStateException if an error accors in C++ addTransceiver 1077 */ addTransceiver(MediaStreamTrack track)1078 public RtpTransceiver addTransceiver(MediaStreamTrack track) { 1079 return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit()); 1080 } 1081 addTransceiver( MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init)1082 public RtpTransceiver addTransceiver( 1083 MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init) { 1084 if (track == null) { 1085 throw new NullPointerException("No MediaStreamTrack specified for addTransceiver."); 1086 } 1087 if (init == null) { 1088 init = new RtpTransceiver.RtpTransceiverInit(); 1089 } 1090 RtpTransceiver newTransceiver = 1091 nativeAddTransceiverWithTrack(track.getNativeMediaStreamTrack(), init); 1092 if (newTransceiver == null) { 1093 throw new IllegalStateException("C++ addTransceiver failed."); 1094 } 1095 transceivers.add(newTransceiver); 1096 return newTransceiver; 1097 } 1098 addTransceiver(MediaStreamTrack.MediaType mediaType)1099 public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) { 1100 return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit()); 1101 } 1102 addTransceiver( MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init)1103 public RtpTransceiver addTransceiver( 1104 MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init) { 1105 if (mediaType == null) { 1106 throw new NullPointerException("No MediaType specified for addTransceiver."); 1107 } 1108 if (init == null) { 1109 init = new RtpTransceiver.RtpTransceiverInit(); 1110 } 1111 RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init); 1112 if (newTransceiver == null) { 1113 throw new IllegalStateException("C++ addTransceiver failed."); 1114 } 1115 transceivers.add(newTransceiver); 1116 return newTransceiver; 1117 } 1118 1119 // Older, non-standard implementation of getStats. 1120 @Deprecated getStats(StatsObserver observer, @Nullable MediaStreamTrack track)1121 public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) { 1122 return nativeOldGetStats(observer, (track == null) ? 0 : track.getNativeMediaStreamTrack()); 1123 } 1124 1125 /** 1126 * Gets stats using the new stats collection API, see webrtc/api/stats/. These 1127 * will replace old stats collection API when the new API has matured enough. 1128 */ getStats(RTCStatsCollectorCallback callback)1129 public void getStats(RTCStatsCollectorCallback callback) { 1130 nativeNewGetStats(callback); 1131 } 1132 1133 /** 1134 * Limits the bandwidth allocated for all RTP streams sent by this 1135 * PeerConnection. Pass null to leave a value unchanged. 1136 */ setBitrate(Integer min, Integer current, Integer max)1137 public boolean setBitrate(Integer min, Integer current, Integer max) { 1138 return nativeSetBitrate(min, current, max); 1139 } 1140 1141 /** 1142 * Starts recording an RTC event log. 1143 * 1144 * Ownership of the file is transfered to the native code. If an RTC event 1145 * log is already being recorded, it will be stopped and a new one will start 1146 * using the provided file. Logging will continue until the stopRtcEventLog 1147 * function is called. The max_size_bytes argument is ignored, it is added 1148 * for future use. 1149 */ startRtcEventLog(int file_descriptor, int max_size_bytes)1150 public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) { 1151 return nativeStartRtcEventLog(file_descriptor, max_size_bytes); 1152 } 1153 1154 /** 1155 * Stops recording an RTC event log. If no RTC event log is currently being 1156 * recorded, this call will have no effect. 1157 */ stopRtcEventLog()1158 public void stopRtcEventLog() { 1159 nativeStopRtcEventLog(); 1160 } 1161 1162 // TODO(fischman): add support for DTMF-related methods once that API 1163 // stabilizes. signalingState()1164 public SignalingState signalingState() { 1165 return nativeSignalingState(); 1166 } 1167 iceConnectionState()1168 public IceConnectionState iceConnectionState() { 1169 return nativeIceConnectionState(); 1170 } 1171 connectionState()1172 public PeerConnectionState connectionState() { 1173 return nativeConnectionState(); 1174 } 1175 iceGatheringState()1176 public IceGatheringState iceGatheringState() { 1177 return nativeIceGatheringState(); 1178 } 1179 close()1180 public void close() { 1181 nativeClose(); 1182 } 1183 1184 /** 1185 * Free native resources associated with this PeerConnection instance. 1186 * 1187 * This method removes a reference count from the C++ PeerConnection object, 1188 * which should result in it being destroyed. It also calls equivalent 1189 * "dispose" methods on the Java objects attached to this PeerConnection 1190 * (streams, senders, receivers), such that their associated C++ objects 1191 * will also be destroyed. 1192 * 1193 * <p>Note that this method cannot be safely called from an observer callback 1194 * (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for 1195 * example, destroy the PeerConnection after an "ICE failed" callback, you 1196 * must do this asynchronously (in other words, unwind the stack first). See 1197 * <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=3721">bug 1198 * 3721</a> for more details. 1199 */ dispose()1200 public void dispose() { 1201 close(); 1202 for (MediaStream stream : localStreams) { 1203 nativeRemoveLocalStream(stream.getNativeMediaStream()); 1204 stream.dispose(); 1205 } 1206 localStreams.clear(); 1207 for (RtpSender sender : senders) { 1208 sender.dispose(); 1209 } 1210 senders.clear(); 1211 for (RtpReceiver receiver : receivers) { 1212 receiver.dispose(); 1213 } 1214 for (RtpTransceiver transceiver : transceivers) { 1215 transceiver.dispose(); 1216 } 1217 transceivers.clear(); 1218 receivers.clear(); 1219 nativeFreeOwnedPeerConnection(nativePeerConnection); 1220 } 1221 1222 /** Returns a pointer to the native webrtc::PeerConnectionInterface. */ getNativePeerConnection()1223 public long getNativePeerConnection() { 1224 return nativeGetNativePeerConnection(); 1225 } 1226 1227 @CalledByNative getNativeOwnedPeerConnection()1228 long getNativeOwnedPeerConnection() { 1229 return nativePeerConnection; 1230 } 1231 createNativePeerConnectionObserver(Observer observer)1232 public static long createNativePeerConnectionObserver(Observer observer) { 1233 return nativeCreatePeerConnectionObserver(observer); 1234 } 1235 nativeGetNativePeerConnection()1236 private native long nativeGetNativePeerConnection(); nativeGetLocalDescription()1237 private native SessionDescription nativeGetLocalDescription(); nativeGetRemoteDescription()1238 private native SessionDescription nativeGetRemoteDescription(); nativeGetCertificate()1239 private native RtcCertificatePem nativeGetCertificate(); nativeCreateDataChannel(String label, DataChannel.Init init)1240 private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init); nativeCreateOffer(SdpObserver observer, MediaConstraints constraints)1241 private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints); nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints)1242 private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints); nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp)1243 private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp); nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp)1244 private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp); nativeSetAudioPlayout(boolean playout)1245 private native void nativeSetAudioPlayout(boolean playout); nativeSetAudioRecording(boolean recording)1246 private native void nativeSetAudioRecording(boolean recording); nativeSetBitrate(Integer min, Integer current, Integer max)1247 private native boolean nativeSetBitrate(Integer min, Integer current, Integer max); nativeSignalingState()1248 private native SignalingState nativeSignalingState(); nativeIceConnectionState()1249 private native IceConnectionState nativeIceConnectionState(); nativeConnectionState()1250 private native PeerConnectionState nativeConnectionState(); nativeIceGatheringState()1251 private native IceGatheringState nativeIceGatheringState(); nativeClose()1252 private native void nativeClose(); nativeCreatePeerConnectionObserver(Observer observer)1253 private static native long nativeCreatePeerConnectionObserver(Observer observer); nativeFreeOwnedPeerConnection(long ownedPeerConnection)1254 private static native void nativeFreeOwnedPeerConnection(long ownedPeerConnection); nativeSetConfiguration(RTCConfiguration config)1255 private native boolean nativeSetConfiguration(RTCConfiguration config); nativeAddIceCandidate( String sdpMid, int sdpMLineIndex, String iceCandidateSdp)1256 private native boolean nativeAddIceCandidate( 1257 String sdpMid, int sdpMLineIndex, String iceCandidateSdp); nativeRemoveIceCandidates(final IceCandidate[] candidates)1258 private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates); nativeAddLocalStream(long stream)1259 private native boolean nativeAddLocalStream(long stream); nativeRemoveLocalStream(long stream)1260 private native void nativeRemoveLocalStream(long stream); nativeOldGetStats(StatsObserver observer, long nativeTrack)1261 private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack); nativeNewGetStats(RTCStatsCollectorCallback callback)1262 private native void nativeNewGetStats(RTCStatsCollectorCallback callback); nativeCreateSender(String kind, String stream_id)1263 private native RtpSender nativeCreateSender(String kind, String stream_id); nativeGetSenders()1264 private native List<RtpSender> nativeGetSenders(); nativeGetReceivers()1265 private native List<RtpReceiver> nativeGetReceivers(); nativeGetTransceivers()1266 private native List<RtpTransceiver> nativeGetTransceivers(); nativeAddTrack(long track, List<String> streamIds)1267 private native RtpSender nativeAddTrack(long track, List<String> streamIds); nativeRemoveTrack(long sender)1268 private native boolean nativeRemoveTrack(long sender); nativeAddTransceiverWithTrack( long track, RtpTransceiver.RtpTransceiverInit init)1269 private native RtpTransceiver nativeAddTransceiverWithTrack( 1270 long track, RtpTransceiver.RtpTransceiverInit init); nativeAddTransceiverOfType( MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init)1271 private native RtpTransceiver nativeAddTransceiverOfType( 1272 MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init); nativeStartRtcEventLog(int file_descriptor, int max_size_bytes)1273 private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes); nativeStopRtcEventLog()1274 private native void nativeStopRtcEventLog(); 1275 } 1276