diff --git a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java index fb11e4ae0b..35b2077c15 100644 --- a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java @@ -132,7 +132,6 @@ public class PeerConnectionClient { private VideoSink localRender; private List remoteRenders; private SignalingParameters signalingParameters; - private MediaConstraints pcConstraints; private int videoWidth; private int videoHeight; private int videoFps; @@ -541,17 +540,6 @@ public class PeerConnectionClient { } private void createMediaConstraintsInternal() { - // Create peer connection constraints. - pcConstraints = new MediaConstraints(); - // Enable DTLS for normal calls and disable for loopback calls. - if (peerConnectionParameters.loopback) { - pcConstraints.optional.add( - new MediaConstraints.KeyValuePair(DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT, "false")); - } else { - pcConstraints.optional.add( - new MediaConstraints.KeyValuePair(DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT, "true")); - } - // Check if there is a camera on device and disable video call if not. if (videoCapturer == null) { Log.w(TAG, "No camera on device. Switch to audio only call."); @@ -615,7 +603,6 @@ public class PeerConnectionClient { } Log.d(TAG, "Create peer connection."); - Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); queuedRemoteCandidates = new ArrayList<>(); if (videoCallEnabled) { @@ -633,8 +620,10 @@ public class PeerConnectionClient { rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY; // Use ECDSA encryption. rtcConfig.keyType = PeerConnection.KeyType.ECDSA; + // Enable DTLS for normal calls and disable for loopback calls. + rtcConfig.enableDtlsSrtp = !peerConnectionParameters.loopback; - peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcObserver); + peerConnection = factory.createPeerConnection(rtcConfig, pcObserver); if (dataChannelEnabled) { DataChannel.Init init = new DataChannel.Init(); diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java index 7c4e91d3f1..6c278725aa 100644 --- a/sdk/android/api/org/webrtc/PeerConnection.java +++ b/sdk/android/api/org/webrtc/PeerConnection.java @@ -357,6 +357,17 @@ public class PeerConnection { public int maxIPv6Networks; 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; + public Integer screencastMinBitrate; + public Boolean combinedAudioVideoBwe; + public Boolean enableDtlsSrtp; + // This is an optional wrapper for the C++ webrtc::TurnCustomizer. public TurnCustomizer turnCustomizer; @@ -383,6 +394,14 @@ public class PeerConnection { disableIPv6OnWifi = false; maxIPv6Networks = 5; iceRegatherIntervalRange = null; + disableIpv6 = false; + enableDscp = false; + enableCpuOveruseDetection = true; + enableRtpDataChannel = false; + suspendBelowMinBitrate = false; + screencastMinBitrate = null; + combinedAudioVideoBwe = null; + enableDtlsSrtp = null; } @CalledByNative("RTCConfiguration") @@ -484,6 +503,46 @@ public class PeerConnection { 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; + } + + @CalledByNative("RTCConfiguration") + Integer getScreencastMinBitrate() { + return screencastMinBitrate; + } + + @CalledByNative("RTCConfiguration") + Boolean getCombinedAudioVideoBwe() { + return combinedAudioVideoBwe; + } + + @CalledByNative("RTCConfiguration") + Boolean getEnableDtlsSrtp() { + return enableDtlsSrtp; + } }; private final List localStreams = new ArrayList<>(); diff --git a/sdk/android/api/org/webrtc/PeerConnectionFactory.java b/sdk/android/api/org/webrtc/PeerConnectionFactory.java index a7bf4c6acd..c51ebd2b9c 100644 --- a/sdk/android/api/org/webrtc/PeerConnectionFactory.java +++ b/sdk/android/api/org/webrtc/PeerConnectionFactory.java @@ -219,6 +219,11 @@ public class PeerConnectionFactory { } } + /** + * Deprecated. PeerConnection constraints are deprecated. Supply values in rtcConfig struct + * instead and use the method without constraints in the signature. + */ + @Deprecated public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, PeerConnection.Observer observer) { long nativeObserver = createNativeObserver(observer); @@ -233,12 +238,28 @@ public class PeerConnectionFactory { return new PeerConnection(nativePeerConnection, nativeObserver); } + /** + * Deprecated. PeerConnection constraints are deprecated. Supply values in rtcConfig struct + * instead and use the method without constraints in the signature. + */ + @Deprecated public PeerConnection createPeerConnection(List iceServers, MediaConstraints constraints, PeerConnection.Observer observer) { PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers); return createPeerConnection(rtcConfig, constraints, observer); } + public PeerConnection createPeerConnection( + List iceServers, PeerConnection.Observer observer) { + PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers); + return createPeerConnection(rtcConfig, observer); + } + + public PeerConnection createPeerConnection( + PeerConnection.RTCConfiguration rtcConfig, PeerConnection.Observer observer) { + return createPeerConnection(rtcConfig, null /* constraints */, observer); + } + public MediaStream createLocalMediaStream(String label) { return new MediaStream(createNativeLocalMediaStream(nativeFactory, label)); } diff --git a/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java b/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java index f1a0395723..a88bd4eb15 100644 --- a/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java +++ b/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java @@ -23,14 +23,14 @@ import java.io.File; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.IdentityHashMap; -import java.util.ArrayList; import java.util.List; -import java.util.Queue; -import java.util.ArrayDeque; import java.util.Map; +import java.util.Queue; import java.util.TreeSet; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -661,10 +661,8 @@ public class PeerConnectionTest { config.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY; config.iceRegatherIntervalRange = new PeerConnection.IntervalRange(1000, 2000); - MediaConstraints constraints = new MediaConstraints(); ObserverExpectations offeringExpectations = new ObserverExpectations("PCTest:offerer"); - PeerConnection offeringPC = - factory.createPeerConnection(config, constraints, offeringExpectations); + PeerConnection offeringPC = factory.createPeerConnection(config, offeringExpectations); assertNotNull(offeringPC); } @@ -678,9 +676,6 @@ public class PeerConnectionTest { options.networkIgnoreMask = 0; PeerConnectionFactory factory = new PeerConnectionFactory(options); - MediaConstraints pcConstraints = new MediaConstraints(); - pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true")); - List iceServers = new ArrayList<>(); iceServers.add( PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()); @@ -688,14 +683,16 @@ public class PeerConnectionTest { .setUsername("fakeUsername") .setPassword("fakePassword") .createIceServer()); + + PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers); + rtcConfig.enableDtlsSrtp = true; + ObserverExpectations offeringExpectations = new ObserverExpectations("PCTest:offerer"); - PeerConnection offeringPC = - factory.createPeerConnection(iceServers, pcConstraints, offeringExpectations); + PeerConnection offeringPC = factory.createPeerConnection(rtcConfig, offeringExpectations); assertNotNull(offeringPC); ObserverExpectations answeringExpectations = new ObserverExpectations("PCTest:answerer"); - PeerConnection answeringPC = - factory.createPeerConnection(iceServers, pcConstraints, answeringExpectations); + PeerConnection answeringPC = factory.createPeerConnection(rtcConfig, answeringExpectations); assertNotNull(answeringPC); // We want to use the same camera for offerer & answerer, so create it here @@ -918,9 +915,6 @@ public class PeerConnectionTest { options.networkIgnoreMask = 0; PeerConnectionFactory factory = new PeerConnectionFactory(options); - MediaConstraints pcConstraints = new MediaConstraints(); - pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true")); - List iceServers = new ArrayList<>(); iceServers.add( PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()); @@ -928,14 +922,16 @@ public class PeerConnectionTest { .setUsername("fakeUsername") .setPassword("fakePassword") .createIceServer()); + + PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers); + rtcConfig.enableDtlsSrtp = true; + ObserverExpectations offeringExpectations = new ObserverExpectations("PCTest:offerer"); - PeerConnection offeringPC = - factory.createPeerConnection(iceServers, pcConstraints, offeringExpectations); + PeerConnection offeringPC = factory.createPeerConnection(rtcConfig, offeringExpectations); assertNotNull(offeringPC); ObserverExpectations answeringExpectations = new ObserverExpectations("PCTest:answerer"); - PeerConnection answeringPC = - factory.createPeerConnection(iceServers, pcConstraints, answeringExpectations); + PeerConnection answeringPC = factory.createPeerConnection(rtcConfig, answeringExpectations); assertNotNull(answeringPC); offeringExpectations.expectRenegotiationNeeded(); @@ -1073,21 +1069,19 @@ public class PeerConnectionTest { options.networkIgnoreMask = 0; PeerConnectionFactory factory = new PeerConnectionFactory(options); - MediaConstraints pcConstraints = new MediaConstraints(); - pcConstraints.mandatory.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true")); - List iceServers = new ArrayList<>(); iceServers.add( PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()); + PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers); + rtcConfig.enableDtlsSrtp = true; + ObserverExpectations offeringExpectations = new ObserverExpectations("PCTest:offerer"); - PeerConnection offeringPC = - factory.createPeerConnection(iceServers, pcConstraints, offeringExpectations); + PeerConnection offeringPC = factory.createPeerConnection(rtcConfig, offeringExpectations); assertNotNull(offeringPC); ObserverExpectations answeringExpectations = new ObserverExpectations("PCTest:answerer"); - PeerConnection answeringPC = - factory.createPeerConnection(iceServers, pcConstraints, answeringExpectations); + PeerConnection answeringPC = factory.createPeerConnection(rtcConfig, answeringExpectations); assertNotNull(answeringPC); // We want to use the same camera for offerer & answerer, so create it here @@ -1269,8 +1263,7 @@ public class PeerConnectionTest { PeerConnectionFactory.Options options = new PeerConnectionFactory.Options(); PeerConnectionFactory factory = new PeerConnectionFactory(options); - // This test is fine with default PC constraints and no ICE servers. - MediaConstraints pcConstraints = new MediaConstraints(); + // This test is fine with no ICE servers. List iceServers = new ArrayList<>(); // Use OfferToReceiveAudio/Video to ensure every offer has an audio and @@ -1285,13 +1278,11 @@ public class PeerConnectionTest { // This PeerConnection will only be used to generate offers. ObserverExpectations offeringExpectations = new ObserverExpectations("offerer"); - PeerConnection offeringPC = - factory.createPeerConnection(iceServers, pcConstraints, offeringExpectations); + PeerConnection offeringPC = factory.createPeerConnection(iceServers, offeringExpectations); assertNotNull(offeringPC); ObserverExpectations expectations = new ObserverExpectations("PC under test"); - PeerConnection pcUnderTest = - factory.createPeerConnection(iceServers, pcConstraints, expectations); + PeerConnection pcUnderTest = factory.createPeerConnection(iceServers, expectations); assertNotNull(pcUnderTest); // Add offerer media stream with just an audio track. diff --git a/sdk/android/src/jni/jni_helpers.cc b/sdk/android/src/jni/jni_helpers.cc index 6e7f80856a..d1bca15bd5 100644 --- a/sdk/android/src/jni/jni_helpers.cc +++ b/sdk/android/src/jni/jni_helpers.cc @@ -185,6 +185,12 @@ rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer) { return JNI_Integer::Java_Integer_intValue(jni, integer); } +rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, jobject boolean) { + if (IsNull(jni, boolean)) + return rtc::nullopt; + return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean); +} + int64_t JavaToNativeLong(JNIEnv* env, jobject j_long) { return JNI_Long::Java_Long_longValue(env, j_long); } diff --git a/sdk/android/src/jni/jni_helpers.h b/sdk/android/src/jni/jni_helpers.h index 633cf9c8af..40d9886921 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -67,6 +67,7 @@ std::string JavaToStdString(JNIEnv* jni, const jstring& j_string); std::vector JavaToStdVectorStrings(JNIEnv* jni, jobject list); rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer); +rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, jobject boolean); int64_t JavaToNativeLong(JNIEnv* env, jobject j_long); jobject NativeToJavaBoolean(JNIEnv* env, bool b); diff --git a/sdk/android/src/jni/pc/peerconnection.cc b/sdk/android/src/jni/pc/peerconnection.cc index 02892e9b23..4844603144 100644 --- a/sdk/android/src/jni/pc/peerconnection.cc +++ b/sdk/android/src/jni/pc/peerconnection.cc @@ -173,6 +173,23 @@ void JavaToNativeRTCConfiguration( rtc_config->turn_customizer = reinterpret_cast( Java_TurnCustomizer_getNativeTurnCustomizer(jni, j_turn_customizer)); } + + rtc_config->disable_ipv6 = + Java_RTCConfiguration_getDisableIpv6(jni, j_rtc_config); + rtc_config->media_config.enable_dscp = + Java_RTCConfiguration_getEnableDscp(jni, j_rtc_config); + rtc_config->media_config.video.enable_cpu_overuse_detection = + Java_RTCConfiguration_getEnableCpuOveruseDetection(jni, j_rtc_config); + rtc_config->enable_rtp_data_channel = + Java_RTCConfiguration_getEnableRtpDataChannel(jni, j_rtc_config); + rtc_config->media_config.video.suspend_below_min_bitrate = + Java_RTCConfiguration_getSuspendBelowMinBitrate(jni, j_rtc_config); + rtc_config->screencast_min_bitrate = JavaToNativeOptionalInt( + jni, Java_RTCConfiguration_getScreencastMinBitrate(jni, j_rtc_config)); + rtc_config->combined_audio_video_bwe = JavaToNativeOptionalBool( + jni, Java_RTCConfiguration_getCombinedAudioVideoBwe(jni, j_rtc_config)); + rtc_config->enable_dtls_srtp = JavaToNativeOptionalBool( + jni, Java_RTCConfiguration_getEnableDtlsSrtp(jni, j_rtc_config)); } rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, jobject j_rtc_config) { @@ -545,7 +562,9 @@ JNI_FUNCTION_DECLARATION(jboolean, PeerConnectionInterface::RTCConfiguration rtc_config( PeerConnectionInterface::RTCConfigurationType::kAggressive); JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config); - CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config); + if (observer && observer->constraints()) { + CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config); + } return ExtractNativePC(jni, j_pc)->SetConfiguration(rtc_config); } diff --git a/sdk/android/src/jni/pc/peerconnectionfactory.cc b/sdk/android/src/jni/pc/peerconnectionfactory.cc index 71b48182bb..1eb077022b 100644 --- a/sdk/android/src/jni/pc/peerconnectionfactory.cc +++ b/sdk/android/src/jni/pc/peerconnectionfactory.cc @@ -464,8 +464,10 @@ JNI_FUNCTION_DECLARATION(jlong, PeerConnectionObserverJni* observer = reinterpret_cast(observer_p); - observer->SetConstraints(JavaToNativeMediaConstraints(jni, j_constraints)); - CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config); + if (j_constraints != nullptr) { + observer->SetConstraints(JavaToNativeMediaConstraints(jni, j_constraints)); + CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config); + } rtc::scoped_refptr pc( f->CreatePeerConnection(rtc_config, nullptr, nullptr, observer)); return (jlong)pc.release();