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