mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00

This reverts commit117d847901
. Reason for revert: Downstream error has been corrected. Original change's description: > Revert "Reland: Remove unsupported configuration value, `allow_codec_switching`" > > This reverts commit23501a2aa6
. > > Reason for revert: Breaks downstream features > > Original change's description: > > Reland: Remove unsupported configuration value, `allow_codec_switching` > > > > This reverts commit6b0c5babe0
. > > > > Reason for revert: Relanding once downstream issues have been addressed > > > > Original change's description: > > > Revert "Remove unsupported configuration value, `allow_codec_switching`" > > > > > > This reverts commit8f7a17f80f
. > > > > > > Reason for revert: breaks downstream > > > > > > Original change's description: > > > > Remove unsupported configuration value, `allow_codec_switching` > > > > > > > > Bug: webrtc:11341 > > > > Change-Id: I8ff598848996bd63ccc572e11f8f69c892a4a459 > > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324284 > > > > Reviewed-by: Philip Eliasson <philipel@webrtc.org> > > > > Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> > > > > Cr-Commit-Position: refs/heads/main@{#40995} > > > > > > Bug: webrtc:11341 > > > Change-Id: I784fd95062fc71f8dcc139b05121985f60709004 > > > No-Presubmit: true > > > No-Tree-Checks: true > > > No-Try: true > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324780 > > > Owners-Override: Philip Eliasson <philipel@webrtc.org> > > > Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> > > > Commit-Queue: Philip Eliasson <philipel@webrtc.org> > > > Cr-Commit-Position: refs/heads/main@{#40998} > > > > Bug: webrtc:11341 > > Change-Id: I3cb3e699fd76942c51f0f42a99bcb19ac607632e > > No-Presubmit: true > > No-Tree-Checks: true > > No-Try: true > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324782 > > Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> > > Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> > > Cr-Commit-Position: refs/heads/main@{#41032} > > Bug: webrtc:11341 > Change-Id: I0eb8e6a464a8a51e6359caf8f43231dc275c4f20 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/327382 > Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> > Auto-Submit: Tomas Gunnarsson <tommi@webrtc.org> > Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> > Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#41161} Bug: webrtc:11341 Change-Id: I4a5390a3b8c5e665b742fc564709847ad8853ba9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328160 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/main@{#41213}
1316 lines
46 KiB
Java
1316 lines
46 KiB
Java
/*
|
|
* Copyright 2013 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
package org.webrtc;
|
|
|
|
import androidx.annotation.Nullable;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import org.webrtc.CandidatePairChangeEvent;
|
|
import org.webrtc.DataChannel;
|
|
import org.webrtc.MediaStreamTrack;
|
|
import org.webrtc.RtpTransceiver;
|
|
|
|
/**
|
|
* Java-land version of the PeerConnection APIs; wraps the C++ API
|
|
* http://www.webrtc.org/reference/native-apis, which in turn is inspired by the
|
|
* JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
|
|
* http://www.w3.org/TR/mediacapture-streams/
|
|
*/
|
|
public class PeerConnection {
|
|
/** Tracks PeerConnectionInterface::IceGatheringState */
|
|
public enum IceGatheringState {
|
|
NEW,
|
|
GATHERING,
|
|
COMPLETE;
|
|
|
|
@CalledByNative("IceGatheringState")
|
|
static IceGatheringState fromNativeIndex(int nativeIndex) {
|
|
return values()[nativeIndex];
|
|
}
|
|
}
|
|
|
|
/** Tracks PeerConnectionInterface::IceConnectionState */
|
|
public enum IceConnectionState {
|
|
NEW,
|
|
CHECKING,
|
|
CONNECTED,
|
|
COMPLETED,
|
|
FAILED,
|
|
DISCONNECTED,
|
|
CLOSED;
|
|
|
|
@CalledByNative("IceConnectionState")
|
|
static IceConnectionState fromNativeIndex(int nativeIndex) {
|
|
return values()[nativeIndex];
|
|
}
|
|
}
|
|
|
|
/** Tracks PeerConnectionInterface::PeerConnectionState */
|
|
public enum PeerConnectionState {
|
|
NEW,
|
|
CONNECTING,
|
|
CONNECTED,
|
|
DISCONNECTED,
|
|
FAILED,
|
|
CLOSED;
|
|
|
|
@CalledByNative("PeerConnectionState")
|
|
static PeerConnectionState fromNativeIndex(int nativeIndex) {
|
|
return values()[nativeIndex];
|
|
}
|
|
}
|
|
|
|
/** Tracks PeerConnectionInterface::TlsCertPolicy */
|
|
public enum TlsCertPolicy {
|
|
TLS_CERT_POLICY_SECURE,
|
|
TLS_CERT_POLICY_INSECURE_NO_CHECK,
|
|
}
|
|
|
|
/** Tracks PeerConnectionInterface::SignalingState */
|
|
public enum SignalingState {
|
|
STABLE,
|
|
HAVE_LOCAL_OFFER,
|
|
HAVE_LOCAL_PRANSWER,
|
|
HAVE_REMOTE_OFFER,
|
|
HAVE_REMOTE_PRANSWER,
|
|
CLOSED;
|
|
|
|
@CalledByNative("SignalingState")
|
|
static SignalingState fromNativeIndex(int nativeIndex) {
|
|
return values()[nativeIndex];
|
|
}
|
|
}
|
|
|
|
/** Java version of PeerConnectionObserver. */
|
|
public static interface Observer {
|
|
/** Triggered when the SignalingState changes. */
|
|
@CalledByNative("Observer") void onSignalingChange(SignalingState newState);
|
|
|
|
/** Triggered when the IceConnectionState changes. */
|
|
@CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState);
|
|
|
|
/* Triggered when the standard-compliant state transition of IceConnectionState happens. */
|
|
@CalledByNative("Observer")
|
|
default void onStandardizedIceConnectionChange(IceConnectionState newState) {}
|
|
|
|
/** Triggered when the PeerConnectionState changes. */
|
|
@CalledByNative("Observer")
|
|
default void onConnectionChange(PeerConnectionState newState) {}
|
|
|
|
/** Triggered when the ICE connection receiving status changes. */
|
|
@CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving);
|
|
|
|
/** Triggered when the IceGatheringState changes. */
|
|
@CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState);
|
|
|
|
/** Triggered when a new ICE candidate has been found. */
|
|
@CalledByNative("Observer") void onIceCandidate(IceCandidate candidate);
|
|
|
|
/** Triggered when gathering of an ICE candidate failed. */
|
|
default @CalledByNative("Observer") void onIceCandidateError(IceCandidateErrorEvent event) {}
|
|
|
|
/** Triggered when some ICE candidates have been removed. */
|
|
@CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates);
|
|
|
|
/** Triggered when the ICE candidate pair is changed. */
|
|
@CalledByNative("Observer")
|
|
default void onSelectedCandidatePairChanged(CandidatePairChangeEvent event) {}
|
|
|
|
/** Triggered when media is received on a new stream from remote peer. */
|
|
@CalledByNative("Observer") void onAddStream(MediaStream stream);
|
|
|
|
/** Triggered when a remote peer close a stream. */
|
|
@CalledByNative("Observer") void onRemoveStream(MediaStream stream);
|
|
|
|
/** Triggered when a remote peer opens a DataChannel. */
|
|
@CalledByNative("Observer") void onDataChannel(DataChannel dataChannel);
|
|
|
|
/** Triggered when renegotiation is necessary. */
|
|
@CalledByNative("Observer") void onRenegotiationNeeded();
|
|
|
|
/**
|
|
* Triggered when a new track is signaled by the remote peer, as a result of
|
|
* setRemoteDescription.
|
|
*/
|
|
@CalledByNative("Observer")
|
|
default void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams){};
|
|
|
|
/**
|
|
* Triggered when a previously added remote track is removed by the remote
|
|
* peer, as a result of setRemoteDescription.
|
|
*/
|
|
@CalledByNative("Observer") default void onRemoveTrack(RtpReceiver receiver){};
|
|
|
|
/**
|
|
* Triggered when the signaling from SetRemoteDescription indicates that a transceiver
|
|
* will be receiving media from a remote endpoint. This is only called if UNIFIED_PLAN
|
|
* semantics are specified. The transceiver will be disposed automatically.
|
|
*/
|
|
@CalledByNative("Observer") default void onTrack(RtpTransceiver transceiver){};
|
|
}
|
|
|
|
/** Java version of PeerConnectionInterface.IceServer. */
|
|
public static class IceServer {
|
|
// List of URIs associated with this server. Valid formats are described
|
|
// in RFC7064 and RFC7065, and more may be added in the future. The "host"
|
|
// part of the URI may contain either an IP address or a hostname.
|
|
@Deprecated public final String uri;
|
|
public final List<String> urls;
|
|
public final String username;
|
|
public final String password;
|
|
public final TlsCertPolicy tlsCertPolicy;
|
|
|
|
// If the URIs in `urls` only contain IP addresses, this field can be used
|
|
// to indicate the hostname, which may be necessary for TLS (using the SNI
|
|
// extension). If `urls` itself contains the hostname, this isn't
|
|
// necessary.
|
|
public final String hostname;
|
|
|
|
// List of protocols to be used in the TLS ALPN extension.
|
|
public final List<String> tlsAlpnProtocols;
|
|
|
|
// List of elliptic curves to be used in the TLS elliptic curves extension.
|
|
// Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
|
|
public final List<String> tlsEllipticCurves;
|
|
|
|
/** Convenience constructor for STUN servers. */
|
|
@Deprecated
|
|
public IceServer(String uri) {
|
|
this(uri, "", "");
|
|
}
|
|
|
|
@Deprecated
|
|
public IceServer(String uri, String username, String password) {
|
|
this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE);
|
|
}
|
|
|
|
@Deprecated
|
|
public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) {
|
|
this(uri, username, password, tlsCertPolicy, "");
|
|
}
|
|
|
|
@Deprecated
|
|
public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
|
|
String hostname) {
|
|
this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null,
|
|
null);
|
|
}
|
|
|
|
private IceServer(String uri, List<String> urls, String username, String password,
|
|
TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols,
|
|
List<String> tlsEllipticCurves) {
|
|
if (uri == null || urls == null || urls.isEmpty()) {
|
|
throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()");
|
|
}
|
|
for (String it : urls) {
|
|
if (it == null) {
|
|
throw new IllegalArgumentException("urls element is null: " + urls);
|
|
}
|
|
}
|
|
if (username == null) {
|
|
throw new IllegalArgumentException("username == null");
|
|
}
|
|
if (password == null) {
|
|
throw new IllegalArgumentException("password == null");
|
|
}
|
|
if (hostname == null) {
|
|
throw new IllegalArgumentException("hostname == null");
|
|
}
|
|
this.uri = uri;
|
|
this.urls = urls;
|
|
this.username = username;
|
|
this.password = password;
|
|
this.tlsCertPolicy = tlsCertPolicy;
|
|
this.hostname = hostname;
|
|
this.tlsAlpnProtocols = tlsAlpnProtocols;
|
|
this.tlsEllipticCurves = tlsEllipticCurves;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
|
|
+ "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(@Nullable Object obj) {
|
|
if (obj == null) {
|
|
return false;
|
|
}
|
|
if (obj == this) {
|
|
return true;
|
|
}
|
|
if (!(obj instanceof IceServer)) {
|
|
return false;
|
|
}
|
|
IceServer other = (IceServer) obj;
|
|
return (uri.equals(other.uri) && urls.equals(other.urls) && username.equals(other.username)
|
|
&& password.equals(other.password) && tlsCertPolicy.equals(other.tlsCertPolicy)
|
|
&& hostname.equals(other.hostname) && tlsAlpnProtocols.equals(other.tlsAlpnProtocols)
|
|
&& tlsEllipticCurves.equals(other.tlsEllipticCurves));
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
Object[] values = {uri, urls, username, password, tlsCertPolicy, hostname, tlsAlpnProtocols,
|
|
tlsEllipticCurves};
|
|
return Arrays.hashCode(values);
|
|
}
|
|
|
|
public static Builder builder(String uri) {
|
|
return new Builder(Collections.singletonList(uri));
|
|
}
|
|
|
|
public static Builder builder(List<String> urls) {
|
|
return new Builder(urls);
|
|
}
|
|
|
|
public static class Builder {
|
|
@Nullable private final List<String> urls;
|
|
private String username = "";
|
|
private String password = "";
|
|
private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
|
|
private String hostname = "";
|
|
private List<String> tlsAlpnProtocols;
|
|
private List<String> tlsEllipticCurves;
|
|
|
|
private Builder(List<String> urls) {
|
|
if (urls == null || urls.isEmpty()) {
|
|
throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls);
|
|
}
|
|
this.urls = urls;
|
|
}
|
|
|
|
public Builder setUsername(String username) {
|
|
this.username = username;
|
|
return this;
|
|
}
|
|
|
|
public Builder setPassword(String password) {
|
|
this.password = password;
|
|
return this;
|
|
}
|
|
|
|
public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) {
|
|
this.tlsCertPolicy = tlsCertPolicy;
|
|
return this;
|
|
}
|
|
|
|
public Builder setHostname(String hostname) {
|
|
this.hostname = hostname;
|
|
return this;
|
|
}
|
|
|
|
public Builder setTlsAlpnProtocols(List<String> tlsAlpnProtocols) {
|
|
this.tlsAlpnProtocols = tlsAlpnProtocols;
|
|
return this;
|
|
}
|
|
|
|
public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
|
|
this.tlsEllipticCurves = tlsEllipticCurves;
|
|
return this;
|
|
}
|
|
|
|
public IceServer createIceServer() {
|
|
return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname,
|
|
tlsAlpnProtocols, tlsEllipticCurves);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("IceServer")
|
|
List<String> getUrls() {
|
|
return urls;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("IceServer")
|
|
String getUsername() {
|
|
return username;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("IceServer")
|
|
String getPassword() {
|
|
return password;
|
|
}
|
|
|
|
@CalledByNative("IceServer")
|
|
TlsCertPolicy getTlsCertPolicy() {
|
|
return tlsCertPolicy;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("IceServer")
|
|
String getHostname() {
|
|
return hostname;
|
|
}
|
|
|
|
@CalledByNative("IceServer")
|
|
List<String> getTlsAlpnProtocols() {
|
|
return tlsAlpnProtocols;
|
|
}
|
|
|
|
@CalledByNative("IceServer")
|
|
List<String> getTlsEllipticCurves() {
|
|
return tlsEllipticCurves;
|
|
}
|
|
}
|
|
|
|
/** Java version of PeerConnectionInterface.IceTransportsType */
|
|
public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }
|
|
|
|
/** Java version of PeerConnectionInterface.BundlePolicy */
|
|
public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }
|
|
|
|
/** Java version of PeerConnectionInterface.RtcpMuxPolicy */
|
|
public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }
|
|
|
|
/** Java version of PeerConnectionInterface.TcpCandidatePolicy */
|
|
public enum TcpCandidatePolicy { ENABLED, DISABLED }
|
|
|
|
/** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
|
|
public enum CandidateNetworkPolicy { ALL, LOW_COST }
|
|
|
|
// Keep in sync with webrtc/rtc_base/network_constants.h.
|
|
public enum AdapterType {
|
|
UNKNOWN(0),
|
|
ETHERNET(1 << 0),
|
|
WIFI(1 << 1),
|
|
CELLULAR(1 << 2),
|
|
VPN(1 << 3),
|
|
LOOPBACK(1 << 4),
|
|
ADAPTER_TYPE_ANY(1 << 5),
|
|
CELLULAR_2G(1 << 6),
|
|
CELLULAR_3G(1 << 7),
|
|
CELLULAR_4G(1 << 8),
|
|
CELLULAR_5G(1 << 9);
|
|
|
|
public final Integer bitMask;
|
|
private AdapterType(Integer bitMask) {
|
|
this.bitMask = bitMask;
|
|
}
|
|
private static final Map<Integer, AdapterType> BY_BITMASK = new HashMap<>();
|
|
static {
|
|
for (AdapterType t : values()) {
|
|
BY_BITMASK.put(t.bitMask, t);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("AdapterType")
|
|
static AdapterType fromNativeIndex(int nativeIndex) {
|
|
return BY_BITMASK.get(nativeIndex);
|
|
}
|
|
}
|
|
|
|
/** Java version of rtc::KeyType */
|
|
public enum KeyType { RSA, ECDSA }
|
|
|
|
/** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
|
|
public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }
|
|
|
|
/** Java version of webrtc::PortPrunePolicy */
|
|
public enum PortPrunePolicy {
|
|
NO_PRUNE, // Do not prune turn port.
|
|
PRUNE_BASED_ON_PRIORITY, // Prune turn port based the priority on the same network
|
|
KEEP_FIRST_READY // Keep the first ready port and prune the rest on the same network.
|
|
}
|
|
|
|
/**
|
|
* Java version of webrtc::SdpSemantics.
|
|
*
|
|
* Configure the SDP semantics used by this PeerConnection. By default, this
|
|
* is UNIFIED_PLAN which is compliant to the WebRTC 1.0 specification. It is
|
|
* possible to overrwite this to the deprecated PLAN_B SDP format, but note
|
|
* that PLAN_B will be deleted at some future date, see
|
|
* https://crbug.com/webrtc/13528.
|
|
*
|
|
* UNIFIED_PLAN will cause PeerConnection to create offers and answers with
|
|
* multiple m= sections where each m= section maps to one RtpSender and one
|
|
* RtpReceiver (an RtpTransceiver), either both audio or both video. This
|
|
* will also cause PeerConnection to ignore all but the first a=ssrc lines
|
|
* that form a Plan B stream.
|
|
*
|
|
* PLAN_B will cause PeerConnection to create offers and answers with at most
|
|
* one audio and one video m= section with multiple RtpSenders and
|
|
* RtpReceivers specified as multiple a=ssrc lines within the section. This
|
|
* will also cause PeerConnection to ignore all but the first m= section of
|
|
* the same media type.
|
|
*/
|
|
public enum SdpSemantics {
|
|
// TODO(https://crbug.com/webrtc/13528): Remove support for PLAN_B.
|
|
@Deprecated PLAN_B,
|
|
UNIFIED_PLAN
|
|
}
|
|
|
|
/** Java version of PeerConnectionInterface.RTCConfiguration */
|
|
// TODO(qingsi): Resolve the naming inconsistency of fields with/without units.
|
|
public static class RTCConfiguration {
|
|
public IceTransportsType iceTransportsType;
|
|
public List<IceServer> iceServers;
|
|
public BundlePolicy bundlePolicy;
|
|
@Nullable public RtcCertificatePem certificate;
|
|
public RtcpMuxPolicy rtcpMuxPolicy;
|
|
public TcpCandidatePolicy tcpCandidatePolicy;
|
|
public CandidateNetworkPolicy candidateNetworkPolicy;
|
|
public int audioJitterBufferMaxPackets;
|
|
public boolean audioJitterBufferFastAccelerate;
|
|
public int iceConnectionReceivingTimeout;
|
|
public int iceBackupCandidatePairPingInterval;
|
|
public KeyType keyType;
|
|
public ContinualGatheringPolicy continualGatheringPolicy;
|
|
public int iceCandidatePoolSize;
|
|
@Deprecated // by the turnPortPrunePolicy. See bugs.webrtc.org/11026
|
|
public boolean pruneTurnPorts;
|
|
public PortPrunePolicy turnPortPrunePolicy;
|
|
public boolean presumeWritableWhenFullyRelayed;
|
|
public boolean surfaceIceCandidatesOnIceTransportTypeChanged;
|
|
// The following fields define intervals in milliseconds at which ICE
|
|
// connectivity checks are sent.
|
|
//
|
|
// We consider ICE is "strongly connected" for an agent when there is at
|
|
// least one candidate pair that currently succeeds in connectivity check
|
|
// from its direction i.e. sending a ping and receives a ping response, AND
|
|
// all candidate pairs have sent a minimum number of pings for connectivity
|
|
// (this number is implementation-specific). Otherwise, ICE is considered in
|
|
// "weak connectivity".
|
|
//
|
|
// Note that the above notion of strong and weak connectivity is not defined
|
|
// in RFC 5245, and they apply to our current ICE implementation only.
|
|
//
|
|
// 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to
|
|
// ALL candidate pairs when ICE is strongly connected,
|
|
// 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL
|
|
// pairs when ICE is weakly connected, and
|
|
// 3) iceCheckMinInterval defines the minimal interval (equivalently the
|
|
// maximum rate) that overrides the above two intervals when either of them
|
|
// is less.
|
|
@Nullable public Integer iceCheckIntervalStrongConnectivityMs;
|
|
@Nullable public Integer iceCheckIntervalWeakConnectivityMs;
|
|
@Nullable public Integer iceCheckMinInterval;
|
|
// The time period in milliseconds for which a candidate pair must wait for response to
|
|
// connectivitiy checks before it becomes unwritable.
|
|
@Nullable public Integer iceUnwritableTimeMs;
|
|
// The minimum number of connectivity checks that a candidate pair must sent without receiving
|
|
// response before it becomes unwritable.
|
|
@Nullable public Integer iceUnwritableMinChecks;
|
|
// The interval in milliseconds at which STUN candidates will resend STUN binding requests
|
|
// to keep NAT bindings open.
|
|
// The default value in the implementation is used if this field is null.
|
|
@Nullable public Integer stunCandidateKeepaliveIntervalMs;
|
|
// The interval in milliseconds of pings sent when the connection is stable and writable.
|
|
// The default value in the implementation is used if this field is null.
|
|
@Nullable public Integer stableWritableConnectionPingIntervalMs;
|
|
public boolean disableIPv6OnWifi;
|
|
// By default, PeerConnection will use a limited number of IPv6 network
|
|
// interfaces, in order to avoid too many ICE candidate pairs being created
|
|
// and delaying ICE completion.
|
|
//
|
|
// Can be set to Integer.MAX_VALUE to effectively disable the limit.
|
|
public int maxIPv6Networks;
|
|
|
|
// These values will be overridden by MediaStream constraints if deprecated constraints-based
|
|
// create peerconnection interface is used.
|
|
public boolean enableDscp;
|
|
public boolean enableCpuOveruseDetection;
|
|
public boolean suspendBelowMinBitrate;
|
|
@Nullable public Integer screencastMinBitrate;
|
|
// Use "Unknown" to represent no preference of adapter types, not the
|
|
// preference of adapters of unknown types.
|
|
public AdapterType networkPreference;
|
|
public SdpSemantics sdpSemantics;
|
|
|
|
// This is an optional wrapper for the C++ webrtc::TurnCustomizer.
|
|
@Nullable public TurnCustomizer turnCustomizer;
|
|
|
|
// Actively reset the SRTP parameters whenever the DTLS transports underneath are reset for
|
|
// every offer/answer negotiation.This is only intended to be a workaround for crbug.com/835958
|
|
public boolean activeResetSrtpParams;
|
|
|
|
/**
|
|
* Defines advanced optional cryptographic settings related to SRTP and
|
|
* frame encryption for native WebRTC. Setting this will overwrite any
|
|
* options set through the PeerConnectionFactory (which is deprecated).
|
|
*/
|
|
@Nullable public CryptoOptions cryptoOptions;
|
|
|
|
/**
|
|
* An optional string that if set will be attached to the
|
|
* TURN_ALLOCATE_REQUEST which can be used to correlate client
|
|
* logs with backend logs
|
|
*/
|
|
@Nullable public String turnLoggingId;
|
|
|
|
/**
|
|
* Allow implicit rollback of local description when remote description
|
|
* conflicts with local description.
|
|
* See: https://w3c.github.io/webrtc-pc/#dom-peerconnection-setremotedescription
|
|
*/
|
|
public boolean enableImplicitRollback;
|
|
|
|
/**
|
|
* Control if "a=extmap-allow-mixed" is included in the offer.
|
|
* See: https://www.chromestatus.com/feature/6269234631933952
|
|
*/
|
|
public boolean offerExtmapAllowMixed;
|
|
|
|
// TODO(deadbeef): Instead of duplicating the defaults here, we should do
|
|
// something to pick up the defaults from C++. The Objective-C equivalent
|
|
// of RTCConfiguration does that.
|
|
public RTCConfiguration(List<IceServer> iceServers) {
|
|
iceTransportsType = IceTransportsType.ALL;
|
|
bundlePolicy = BundlePolicy.BALANCED;
|
|
rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE;
|
|
tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
|
|
candidateNetworkPolicy = CandidateNetworkPolicy.ALL;
|
|
this.iceServers = iceServers;
|
|
audioJitterBufferMaxPackets = 50;
|
|
audioJitterBufferFastAccelerate = false;
|
|
iceConnectionReceivingTimeout = -1;
|
|
iceBackupCandidatePairPingInterval = -1;
|
|
keyType = KeyType.ECDSA;
|
|
continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE;
|
|
iceCandidatePoolSize = 0;
|
|
pruneTurnPorts = false;
|
|
turnPortPrunePolicy = PortPrunePolicy.NO_PRUNE;
|
|
presumeWritableWhenFullyRelayed = false;
|
|
surfaceIceCandidatesOnIceTransportTypeChanged = false;
|
|
iceCheckIntervalStrongConnectivityMs = null;
|
|
iceCheckIntervalWeakConnectivityMs = null;
|
|
iceCheckMinInterval = null;
|
|
iceUnwritableTimeMs = null;
|
|
iceUnwritableMinChecks = null;
|
|
stunCandidateKeepaliveIntervalMs = null;
|
|
stableWritableConnectionPingIntervalMs = null;
|
|
disableIPv6OnWifi = false;
|
|
maxIPv6Networks = 5;
|
|
enableDscp = false;
|
|
enableCpuOveruseDetection = true;
|
|
suspendBelowMinBitrate = false;
|
|
screencastMinBitrate = null;
|
|
networkPreference = AdapterType.UNKNOWN;
|
|
sdpSemantics = SdpSemantics.UNIFIED_PLAN;
|
|
activeResetSrtpParams = false;
|
|
cryptoOptions = null;
|
|
turnLoggingId = null;
|
|
enableImplicitRollback = false;
|
|
offerExtmapAllowMixed = true;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
IceTransportsType getIceTransportsType() {
|
|
return iceTransportsType;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
List<IceServer> getIceServers() {
|
|
return iceServers;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
BundlePolicy getBundlePolicy() {
|
|
return bundlePolicy;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
PortPrunePolicy getTurnPortPrunePolicy() {
|
|
return turnPortPrunePolicy;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
RtcCertificatePem getCertificate() {
|
|
return certificate;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
RtcpMuxPolicy getRtcpMuxPolicy() {
|
|
return rtcpMuxPolicy;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
TcpCandidatePolicy getTcpCandidatePolicy() {
|
|
return tcpCandidatePolicy;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
CandidateNetworkPolicy getCandidateNetworkPolicy() {
|
|
return candidateNetworkPolicy;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
int getAudioJitterBufferMaxPackets() {
|
|
return audioJitterBufferMaxPackets;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getAudioJitterBufferFastAccelerate() {
|
|
return audioJitterBufferFastAccelerate;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
int getIceConnectionReceivingTimeout() {
|
|
return iceConnectionReceivingTimeout;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
int getIceBackupCandidatePairPingInterval() {
|
|
return iceBackupCandidatePairPingInterval;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
KeyType getKeyType() {
|
|
return keyType;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
ContinualGatheringPolicy getContinualGatheringPolicy() {
|
|
return continualGatheringPolicy;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
int getIceCandidatePoolSize() {
|
|
return iceCandidatePoolSize;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getPruneTurnPorts() {
|
|
return pruneTurnPorts;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getPresumeWritableWhenFullyRelayed() {
|
|
return presumeWritableWhenFullyRelayed;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getSurfaceIceCandidatesOnIceTransportTypeChanged() {
|
|
return surfaceIceCandidatesOnIceTransportTypeChanged;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getIceCheckIntervalStrongConnectivity() {
|
|
return iceCheckIntervalStrongConnectivityMs;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getIceCheckIntervalWeakConnectivity() {
|
|
return iceCheckIntervalWeakConnectivityMs;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getIceCheckMinInterval() {
|
|
return iceCheckMinInterval;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getIceUnwritableTimeout() {
|
|
return iceUnwritableTimeMs;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getIceUnwritableMinChecks() {
|
|
return iceUnwritableMinChecks;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getStunCandidateKeepaliveInterval() {
|
|
return stunCandidateKeepaliveIntervalMs;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getStableWritableConnectionPingIntervalMs() {
|
|
return stableWritableConnectionPingIntervalMs;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getDisableIPv6OnWifi() {
|
|
return disableIPv6OnWifi;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
int getMaxIPv6Networks() {
|
|
return maxIPv6Networks;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
TurnCustomizer getTurnCustomizer() {
|
|
return turnCustomizer;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getEnableDscp() {
|
|
return enableDscp;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getEnableCpuOveruseDetection() {
|
|
return enableCpuOveruseDetection;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getSuspendBelowMinBitrate() {
|
|
return suspendBelowMinBitrate;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
Integer getScreencastMinBitrate() {
|
|
return screencastMinBitrate;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
AdapterType getNetworkPreference() {
|
|
return networkPreference;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
SdpSemantics getSdpSemantics() {
|
|
return sdpSemantics;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getActiveResetSrtpParams() {
|
|
return activeResetSrtpParams;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
CryptoOptions getCryptoOptions() {
|
|
return cryptoOptions;
|
|
}
|
|
|
|
@Nullable
|
|
@CalledByNative("RTCConfiguration")
|
|
String getTurnLoggingId() {
|
|
return turnLoggingId;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getEnableImplicitRollback() {
|
|
return enableImplicitRollback;
|
|
}
|
|
|
|
@CalledByNative("RTCConfiguration")
|
|
boolean getOfferExtmapAllowMixed() {
|
|
return offerExtmapAllowMixed;
|
|
}
|
|
};
|
|
|
|
private final List<MediaStream> localStreams = new ArrayList<>();
|
|
private final long nativePeerConnection;
|
|
private List<RtpSender> senders = new ArrayList<>();
|
|
private List<RtpReceiver> receivers = new ArrayList<>();
|
|
private List<RtpTransceiver> transceivers = new ArrayList<>();
|
|
|
|
/**
|
|
* Wraps a PeerConnection created by the factory. Can be used by clients that want to implement
|
|
* their PeerConnection creation in JNI.
|
|
*/
|
|
public PeerConnection(NativePeerConnectionFactory factory) {
|
|
this(factory.createNativePeerConnection());
|
|
}
|
|
|
|
PeerConnection(long nativePeerConnection) {
|
|
this.nativePeerConnection = nativePeerConnection;
|
|
}
|
|
|
|
// JsepInterface.
|
|
public SessionDescription getLocalDescription() {
|
|
return nativeGetLocalDescription();
|
|
}
|
|
|
|
public SessionDescription getRemoteDescription() {
|
|
return nativeGetRemoteDescription();
|
|
}
|
|
|
|
public RtcCertificatePem getCertificate() {
|
|
return nativeGetCertificate();
|
|
}
|
|
|
|
public DataChannel createDataChannel(String label, DataChannel.Init init) {
|
|
return nativeCreateDataChannel(label, init);
|
|
}
|
|
|
|
public void createOffer(SdpObserver observer, MediaConstraints constraints) {
|
|
nativeCreateOffer(observer, constraints);
|
|
}
|
|
|
|
public void createAnswer(SdpObserver observer, MediaConstraints constraints) {
|
|
nativeCreateAnswer(observer, constraints);
|
|
}
|
|
|
|
public void setLocalDescription(SdpObserver observer) {
|
|
nativeSetLocalDescriptionAutomatically(observer);
|
|
}
|
|
|
|
public void setLocalDescription(SdpObserver observer, SessionDescription sdp) {
|
|
nativeSetLocalDescription(observer, sdp);
|
|
}
|
|
|
|
public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) {
|
|
nativeSetRemoteDescription(observer, sdp);
|
|
}
|
|
|
|
/**
|
|
* Tells the PeerConnection that ICE should be restarted.
|
|
*/
|
|
public void restartIce() {
|
|
nativeRestartIce();
|
|
}
|
|
|
|
/**
|
|
* Enables/disables playout of received audio streams. Enabled by default.
|
|
*
|
|
* Note that even if playout is enabled, streams will only be played out if
|
|
* the appropriate SDP is also applied. The main purpose of this API is to
|
|
* be able to control the exact time when audio playout starts.
|
|
*/
|
|
public void setAudioPlayout(boolean playout) {
|
|
nativeSetAudioPlayout(playout);
|
|
}
|
|
|
|
/**
|
|
* Enables/disables recording of transmitted audio streams. Enabled by default.
|
|
*
|
|
* Note that even if recording is enabled, streams will only be recorded if
|
|
* the appropriate SDP is also applied. The main purpose of this API is to
|
|
* be able to control the exact time when audio recording starts.
|
|
*/
|
|
public void setAudioRecording(boolean recording) {
|
|
nativeSetAudioRecording(recording);
|
|
}
|
|
|
|
public boolean setConfiguration(RTCConfiguration config) {
|
|
return nativeSetConfiguration(config);
|
|
}
|
|
|
|
public boolean addIceCandidate(IceCandidate candidate) {
|
|
return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
|
|
}
|
|
|
|
public void addIceCandidate(IceCandidate candidate, AddIceObserver observer) {
|
|
nativeAddIceCandidateWithObserver(
|
|
candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp, observer);
|
|
}
|
|
|
|
public boolean removeIceCandidates(final IceCandidate[] candidates) {
|
|
return nativeRemoveIceCandidates(candidates);
|
|
}
|
|
|
|
/**
|
|
* Adds a new MediaStream to be sent on this peer connection.
|
|
* Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please
|
|
* use addTrack instead.
|
|
*/
|
|
public boolean addStream(MediaStream stream) {
|
|
boolean ret = nativeAddLocalStream(stream.getNativeMediaStream());
|
|
if (!ret) {
|
|
return false;
|
|
}
|
|
localStreams.add(stream);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Removes the given media stream from this peer connection.
|
|
* This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use
|
|
* removeTrack instead.
|
|
*/
|
|
public void removeStream(MediaStream stream) {
|
|
nativeRemoveLocalStream(stream.getNativeMediaStream());
|
|
localStreams.remove(stream);
|
|
}
|
|
|
|
/**
|
|
* Creates an RtpSender without a track.
|
|
*
|
|
* <p>This method allows an application to cause the PeerConnection to negotiate
|
|
* sending/receiving a specific media type, but without having a track to
|
|
* send yet.
|
|
*
|
|
* <p>When the application does want to begin sending a track, it can call
|
|
* RtpSender.setTrack, which doesn't require any additional SDP negotiation.
|
|
*
|
|
* <p>Example use:
|
|
* <pre>
|
|
* {@code
|
|
* audioSender = pc.createSender("audio", "stream1");
|
|
* videoSender = pc.createSender("video", "stream1");
|
|
* // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate
|
|
* // media parameters....
|
|
* // Later, when the endpoint is ready to actually begin sending:
|
|
* audioSender.setTrack(audioTrack, false);
|
|
* videoSender.setTrack(videoTrack, false);
|
|
* }
|
|
* </pre>
|
|
* <p>Note: This corresponds most closely to "addTransceiver" in the official
|
|
* WebRTC API, in that it creates a sender without a track. It was
|
|
* implemented before addTransceiver because it provides useful
|
|
* functionality, and properly implementing transceivers would have required
|
|
* a great deal more work.
|
|
*
|
|
* <p>Note: This is only available with SdpSemantics.PLAN_B specified. Please use
|
|
* addTransceiver instead.
|
|
*
|
|
* @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or
|
|
* "video").
|
|
* @param stream_id The ID of the MediaStream that this sender's track will
|
|
* be associated with when SDP is applied to the remote
|
|
* PeerConnection. If createSender is used to create an
|
|
* audio and video sender that should be synchronized, they
|
|
* should use the same stream ID.
|
|
* @return A new RtpSender object if successful, or null otherwise.
|
|
*/
|
|
public RtpSender createSender(String kind, String stream_id) {
|
|
RtpSender newSender = nativeCreateSender(kind, stream_id);
|
|
if (newSender != null) {
|
|
senders.add(newSender);
|
|
}
|
|
return newSender;
|
|
}
|
|
|
|
/**
|
|
* Gets all RtpSenders associated with this peer connection.
|
|
* Note that calling getSenders will dispose of the senders previously
|
|
* returned.
|
|
*/
|
|
public List<RtpSender> getSenders() {
|
|
for (RtpSender sender : senders) {
|
|
sender.dispose();
|
|
}
|
|
senders = nativeGetSenders();
|
|
return Collections.unmodifiableList(senders);
|
|
}
|
|
|
|
/**
|
|
* Gets all RtpReceivers associated with this peer connection.
|
|
* Note that calling getReceivers will dispose of the receivers previously
|
|
* returned.
|
|
*/
|
|
public List<RtpReceiver> getReceivers() {
|
|
for (RtpReceiver receiver : receivers) {
|
|
receiver.dispose();
|
|
}
|
|
receivers = nativeGetReceivers();
|
|
return Collections.unmodifiableList(receivers);
|
|
}
|
|
|
|
/**
|
|
* Gets all RtpTransceivers associated with this peer connection.
|
|
* Note that calling getTransceivers will dispose of the transceivers previously
|
|
* returned.
|
|
* Note: This is only available with SdpSemantics.UNIFIED_PLAN specified.
|
|
*/
|
|
public List<RtpTransceiver> getTransceivers() {
|
|
for (RtpTransceiver transceiver : transceivers) {
|
|
transceiver.dispose();
|
|
}
|
|
transceivers = nativeGetTransceivers();
|
|
return Collections.unmodifiableList(transceivers);
|
|
}
|
|
|
|
/**
|
|
* Adds a new media stream track to be sent on this peer connection, and returns
|
|
* the newly created RtpSender. If streamIds are specified, the RtpSender will
|
|
* be associated with the streams specified in the streamIds list.
|
|
*
|
|
* @throws IllegalStateException if an error accors in C++ addTrack.
|
|
* An error can occur if:
|
|
* - A sender already exists for the track.
|
|
* - The peer connection is closed.
|
|
*/
|
|
public RtpSender addTrack(MediaStreamTrack track) {
|
|
return addTrack(track, Collections.emptyList());
|
|
}
|
|
|
|
public RtpSender addTrack(MediaStreamTrack track, List<String> streamIds) {
|
|
if (track == null || streamIds == null) {
|
|
throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
|
|
}
|
|
RtpSender newSender = nativeAddTrack(track.getNativeMediaStreamTrack(), streamIds);
|
|
if (newSender == null) {
|
|
throw new IllegalStateException("C++ addTrack failed.");
|
|
}
|
|
senders.add(newSender);
|
|
return newSender;
|
|
}
|
|
|
|
/**
|
|
* Stops sending media from sender. The sender will still appear in getSenders. Future
|
|
* calls to createOffer will mark the m section for the corresponding transceiver as
|
|
* receive only or inactive, as defined in JSEP. Returns true on success.
|
|
*/
|
|
public boolean removeTrack(RtpSender sender) {
|
|
if (sender == null) {
|
|
throw new NullPointerException("No RtpSender specified for removeTrack.");
|
|
}
|
|
return nativeRemoveTrack(sender.getNativeRtpSender());
|
|
}
|
|
|
|
/**
|
|
* Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a
|
|
* transceiver will cause future calls to CreateOffer to add a media description
|
|
* for the corresponding transceiver.
|
|
*
|
|
* <p>The initial value of `mid` in the returned transceiver is null. Setting a
|
|
* new session description may change it to a non-null value.
|
|
*
|
|
* <p>https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
|
|
*
|
|
* <p>If a MediaStreamTrack is specified then a transceiver will be added with a
|
|
* sender set to transmit the given track. The kind
|
|
* of the transceiver (and sender/receiver) will be derived from the kind of
|
|
* the track.
|
|
*
|
|
* <p>If MediaType is specified then a transceiver will be added based upon that type.
|
|
* This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO.
|
|
*
|
|
* <p>Optionally, an RtpTransceiverInit structure can be specified to configure
|
|
* the transceiver from construction. If not specified, the transceiver will
|
|
* default to having a direction of kSendRecv and not be part of any streams.
|
|
*
|
|
* <p>Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified.
|
|
* @throws IllegalStateException if an error accors in C++ addTransceiver
|
|
*/
|
|
public RtpTransceiver addTransceiver(MediaStreamTrack track) {
|
|
return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit());
|
|
}
|
|
|
|
public RtpTransceiver addTransceiver(
|
|
MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init) {
|
|
if (track == null) {
|
|
throw new NullPointerException("No MediaStreamTrack specified for addTransceiver.");
|
|
}
|
|
if (init == null) {
|
|
init = new RtpTransceiver.RtpTransceiverInit();
|
|
}
|
|
RtpTransceiver newTransceiver =
|
|
nativeAddTransceiverWithTrack(track.getNativeMediaStreamTrack(), init);
|
|
if (newTransceiver == null) {
|
|
throw new IllegalStateException("C++ addTransceiver failed.");
|
|
}
|
|
transceivers.add(newTransceiver);
|
|
return newTransceiver;
|
|
}
|
|
|
|
public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) {
|
|
return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit());
|
|
}
|
|
|
|
public RtpTransceiver addTransceiver(
|
|
MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init) {
|
|
if (mediaType == null) {
|
|
throw new NullPointerException("No MediaType specified for addTransceiver.");
|
|
}
|
|
if (init == null) {
|
|
init = new RtpTransceiver.RtpTransceiverInit();
|
|
}
|
|
RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init);
|
|
if (newTransceiver == null) {
|
|
throw new IllegalStateException("C++ addTransceiver failed.");
|
|
}
|
|
transceivers.add(newTransceiver);
|
|
return newTransceiver;
|
|
}
|
|
|
|
// Older, non-standard implementation of getStats.
|
|
@Deprecated
|
|
public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) {
|
|
return nativeOldGetStats(observer, (track == null) ? 0 : track.getNativeMediaStreamTrack());
|
|
}
|
|
|
|
/**
|
|
* Gets stats using the new stats collection API, see webrtc/api/stats/. These
|
|
* will replace old stats collection API when the new API has matured enough.
|
|
*/
|
|
public void getStats(RTCStatsCollectorCallback callback) {
|
|
nativeNewGetStats(callback);
|
|
}
|
|
|
|
/**
|
|
* Gets stats using the new stats collection API, see webrtc/api/stats/. These
|
|
* will replace old stats collection API when the new API has matured enough.
|
|
*/
|
|
public void getStats(RtpSender sender, RTCStatsCollectorCallback callback) {
|
|
nativeNewGetStatsSender(sender.getNativeRtpSender(), callback);
|
|
}
|
|
|
|
/**
|
|
* Gets stats using the new stats collection API, see webrtc/api/stats/. These
|
|
* will replace old stats collection API when the new API has matured enough.
|
|
*/
|
|
public void getStats(RtpReceiver receiver, RTCStatsCollectorCallback callback) {
|
|
nativeNewGetStatsReceiver(receiver.getNativeRtpReceiver(), callback);
|
|
}
|
|
|
|
/**
|
|
* Limits the bandwidth allocated for all RTP streams sent by this
|
|
* PeerConnection. Pass null to leave a value unchanged.
|
|
*/
|
|
public boolean setBitrate(Integer min, Integer current, Integer max) {
|
|
return nativeSetBitrate(min, current, max);
|
|
}
|
|
|
|
/**
|
|
* Starts recording an RTC event log.
|
|
*
|
|
* Ownership of the file is transfered to the native code. If an RTC event
|
|
* log is already being recorded, it will be stopped and a new one will start
|
|
* using the provided file. Logging will continue until the stopRtcEventLog
|
|
* function is called. The max_size_bytes argument is ignored, it is added
|
|
* for future use.
|
|
*/
|
|
public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
|
|
return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
|
|
}
|
|
|
|
/**
|
|
* Stops recording an RTC event log. If no RTC event log is currently being
|
|
* recorded, this call will have no effect.
|
|
*/
|
|
public void stopRtcEventLog() {
|
|
nativeStopRtcEventLog();
|
|
}
|
|
|
|
// TODO(fischman): add support for DTMF-related methods once that API
|
|
// stabilizes.
|
|
public SignalingState signalingState() {
|
|
return nativeSignalingState();
|
|
}
|
|
|
|
public IceConnectionState iceConnectionState() {
|
|
return nativeIceConnectionState();
|
|
}
|
|
|
|
public PeerConnectionState connectionState() {
|
|
return nativeConnectionState();
|
|
}
|
|
|
|
public IceGatheringState iceGatheringState() {
|
|
return nativeIceGatheringState();
|
|
}
|
|
|
|
public void close() {
|
|
nativeClose();
|
|
}
|
|
|
|
/**
|
|
* Free native resources associated with this PeerConnection instance.
|
|
*
|
|
* This method removes a reference count from the C++ PeerConnection object,
|
|
* which should result in it being destroyed. It also calls equivalent
|
|
* "dispose" methods on the Java objects attached to this PeerConnection
|
|
* (streams, senders, receivers), such that their associated C++ objects
|
|
* will also be destroyed.
|
|
*
|
|
* <p>Note that this method cannot be safely called from an observer callback
|
|
* (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for
|
|
* example, destroy the PeerConnection after an "ICE failed" callback, you
|
|
* must do this asynchronously (in other words, unwind the stack first). See
|
|
* <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=3721">bug
|
|
* 3721</a> for more details.
|
|
*/
|
|
public void dispose() {
|
|
close();
|
|
for (MediaStream stream : localStreams) {
|
|
nativeRemoveLocalStream(stream.getNativeMediaStream());
|
|
stream.dispose();
|
|
}
|
|
localStreams.clear();
|
|
for (RtpSender sender : senders) {
|
|
sender.dispose();
|
|
}
|
|
senders.clear();
|
|
for (RtpReceiver receiver : receivers) {
|
|
receiver.dispose();
|
|
}
|
|
for (RtpTransceiver transceiver : transceivers) {
|
|
transceiver.dispose();
|
|
}
|
|
transceivers.clear();
|
|
receivers.clear();
|
|
nativeFreeOwnedPeerConnection(nativePeerConnection);
|
|
}
|
|
|
|
/** Returns a pointer to the native webrtc::PeerConnectionInterface. */
|
|
public long getNativePeerConnection() {
|
|
return nativeGetNativePeerConnection();
|
|
}
|
|
|
|
@CalledByNative
|
|
long getNativeOwnedPeerConnection() {
|
|
return nativePeerConnection;
|
|
}
|
|
|
|
public static long createNativePeerConnectionObserver(Observer observer) {
|
|
return nativeCreatePeerConnectionObserver(observer);
|
|
}
|
|
|
|
private native long nativeGetNativePeerConnection();
|
|
private native SessionDescription nativeGetLocalDescription();
|
|
private native SessionDescription nativeGetRemoteDescription();
|
|
private native RtcCertificatePem nativeGetCertificate();
|
|
private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init);
|
|
private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints);
|
|
private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints);
|
|
private native void nativeSetLocalDescriptionAutomatically(SdpObserver observer);
|
|
private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp);
|
|
private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp);
|
|
private native void nativeRestartIce();
|
|
private native void nativeSetAudioPlayout(boolean playout);
|
|
private native void nativeSetAudioRecording(boolean recording);
|
|
private native boolean nativeSetBitrate(Integer min, Integer current, Integer max);
|
|
private native SignalingState nativeSignalingState();
|
|
private native IceConnectionState nativeIceConnectionState();
|
|
private native PeerConnectionState nativeConnectionState();
|
|
private native IceGatheringState nativeIceGatheringState();
|
|
private native void nativeClose();
|
|
private static native long nativeCreatePeerConnectionObserver(Observer observer);
|
|
private static native void nativeFreeOwnedPeerConnection(long ownedPeerConnection);
|
|
private native boolean nativeSetConfiguration(RTCConfiguration config);
|
|
private native boolean nativeAddIceCandidate(
|
|
String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
|
|
private native void nativeAddIceCandidateWithObserver(
|
|
String sdpMid, int sdpMLineIndex, String iceCandidateSdp, AddIceObserver observer);
|
|
private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
|
|
private native boolean nativeAddLocalStream(long stream);
|
|
private native void nativeRemoveLocalStream(long stream);
|
|
private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
|
|
private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
|
|
private native void nativeNewGetStatsSender(long sender, RTCStatsCollectorCallback callback);
|
|
private native void nativeNewGetStatsReceiver(long receiver, RTCStatsCollectorCallback callback);
|
|
private native RtpSender nativeCreateSender(String kind, String stream_id);
|
|
private native List<RtpSender> nativeGetSenders();
|
|
private native List<RtpReceiver> nativeGetReceivers();
|
|
private native List<RtpTransceiver> nativeGetTransceivers();
|
|
private native RtpSender nativeAddTrack(long track, List<String> streamIds);
|
|
private native boolean nativeRemoveTrack(long sender);
|
|
private native RtpTransceiver nativeAddTransceiverWithTrack(
|
|
long track, RtpTransceiver.RtpTransceiverInit init);
|
|
private native RtpTransceiver nativeAddTransceiverOfType(
|
|
MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init);
|
|
private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
|
|
private native void nativeStopRtcEventLog();
|
|
}
|