| /* | |
| * 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 java.util.ArrayList; | |
| import java.util.Collections; | |
| import java.util.List; | |
| import javax.annotation.Nullable; | |
| /** | |
| * 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::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 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 some ICE candidates have been removed. */ | |
| @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates); | |
| /** 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") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams); | |
| /** | |
| * 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 + "]"; | |
| } | |
| 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, | |
| ETHERNET, | |
| WIFI, | |
| CELLULAR, | |
| VPN, | |
| LOOPBACK, | |
| } | |
| /** 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 rtc::IntervalRange */ | |
| public static class IntervalRange { | |
| private final int min; | |
| private final int max; | |
| public IntervalRange(int min, int max) { | |
| this.min = min; | |
| this.max = max; | |
| } | |
| @CalledByNative("IntervalRange") | |
| public int getMin() { | |
| return min; | |
| } | |
| @CalledByNative("IntervalRange") | |
| public int getMax() { | |
| return max; | |
| } | |
| } | |
| /** | |
| * Java version of webrtc::SdpSemantics. | |
| * | |
| * Configure the SDP semantics used by this PeerConnection. Note that the | |
| * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The | |
| * RtpTransceiver API is only available with UNIFIED_PLAN semantics. | |
| * | |
| * <p>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. | |
| * | |
| * <p>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. | |
| * | |
| * <p>For users who wish to send multiple audio/video streams and need to stay | |
| * interoperable with legacy WebRTC implementations, specify PLAN_B. | |
| * | |
| * <p>For users who wish to send multiple audio/video streams and/or wish to | |
| * use the new RtpTransceiver API, specify UNIFIED_PLAN. | |
| */ | |
| public enum SdpSemantics { 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; | |
| 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; | |
| public boolean pruneTurnPorts; | |
| public boolean presumeWritableWhenFullyRelayed; | |
| // 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; | |
| 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; | |
| @Nullable public IntervalRange iceRegatherIntervalRange; | |
| // These values will be overridden by MediaStream constraints if deprecated constraints-based | |
| // create peerconnection interface is used. | |
| public boolean disableIpv6; | |
| public boolean enableDscp; | |
| public boolean enableCpuOveruseDetection; | |
| public boolean enableRtpDataChannel; | |
| public boolean suspendBelowMinBitrate; | |
| @Nullable public Integer screencastMinBitrate; | |
| @Nullable public Boolean combinedAudioVideoBwe; | |
| @Nullable public Boolean enableDtlsSrtp; | |
| // 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; | |
| // 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; | |
| presumeWritableWhenFullyRelayed = false; | |
| iceCheckIntervalStrongConnectivityMs = null; | |
| iceCheckIntervalWeakConnectivityMs = null; | |
| iceCheckMinInterval = null; | |
| iceUnwritableTimeMs = null; | |
| iceUnwritableMinChecks = null; | |
| stunCandidateKeepaliveIntervalMs = null; | |
| disableIPv6OnWifi = false; | |
| maxIPv6Networks = 5; | |
| iceRegatherIntervalRange = null; | |
| disableIpv6 = false; | |
| enableDscp = false; | |
| enableCpuOveruseDetection = true; | |
| enableRtpDataChannel = false; | |
| suspendBelowMinBitrate = false; | |
| screencastMinBitrate = null; | |
| combinedAudioVideoBwe = null; | |
| enableDtlsSrtp = null; | |
| networkPreference = AdapterType.UNKNOWN; | |
| sdpSemantics = SdpSemantics.PLAN_B; | |
| activeResetSrtpParams = false; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| IceTransportsType getIceTransportsType() { | |
| return iceTransportsType; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| List<IceServer> getIceServers() { | |
| return iceServers; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| BundlePolicy getBundlePolicy() { | |
| return bundlePolicy; | |
| } | |
| @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; | |
| } | |
| @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; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getDisableIPv6OnWifi() { | |
| return disableIPv6OnWifi; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| int getMaxIPv6Networks() { | |
| return maxIPv6Networks; | |
| } | |
| @Nullable | |
| @CalledByNative("RTCConfiguration") | |
| IntervalRange getIceRegatherIntervalRange() { | |
| return iceRegatherIntervalRange; | |
| } | |
| @Nullable | |
| @CalledByNative("RTCConfiguration") | |
| TurnCustomizer getTurnCustomizer() { | |
| return turnCustomizer; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getDisableIpv6() { | |
| return disableIpv6; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getEnableDscp() { | |
| return enableDscp; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getEnableCpuOveruseDetection() { | |
| return enableCpuOveruseDetection; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getEnableRtpDataChannel() { | |
| return enableRtpDataChannel; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getSuspendBelowMinBitrate() { | |
| return suspendBelowMinBitrate; | |
| } | |
| @Nullable | |
| @CalledByNative("RTCConfiguration") | |
| Integer getScreencastMinBitrate() { | |
| return screencastMinBitrate; | |
| } | |
| @Nullable | |
| @CalledByNative("RTCConfiguration") | |
| Boolean getCombinedAudioVideoBwe() { | |
| return combinedAudioVideoBwe; | |
| } | |
| @Nullable | |
| @CalledByNative("RTCConfiguration") | |
| Boolean getEnableDtlsSrtp() { | |
| return enableDtlsSrtp; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| AdapterType getNetworkPreference() { | |
| return networkPreference; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| SdpSemantics getSdpSemantics() { | |
| return sdpSemantics; | |
| } | |
| @CalledByNative("RTCConfiguration") | |
| boolean getActiveResetSrtpParams() { | |
| return activeResetSrtpParams; | |
| } | |
| }; | |
| 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 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, SessionDescription sdp) { | |
| nativeSetLocalDescription(observer, sdp); | |
| } | |
| public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) { | |
| nativeSetRemoteDescription(observer, sdp); | |
| } | |
| /** | |
| * 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 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); | |
| } | |
| /** | |
| * 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 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 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 nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp); | |
| private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp); | |
| 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 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 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 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(); | |
| } |