From cac1b381359652fe623a1bdd320f0877b7b7a300 Mon Sep 17 00:00:00 2001 From: Jiayang Liu Date: Thu, 30 Apr 2015 12:35:24 -0700 Subject: [PATCH] Expose RTCConfiguration to java JNI and add an option to disable TCP BUG=4585, 4589 R=glaznev@webrtc.org, juberti@google.com, pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/49809004 Cr-Commit-Position: refs/heads/master@{#9125} --- .../webrtc/java/jni/classreferenceholder.cc | 3 + .../app/webrtc/java/jni/peerconnection_jni.cc | 111 +++++++++++++++++- .../java/src/org/webrtc/PeerConnection.java | 31 +++++ .../src/org/webrtc/PeerConnectionFactory.java | 15 ++- talk/app/webrtc/peerconnection.cc | 5 + talk/app/webrtc/peerconnectioninterface.h | 11 +- .../appspot/apprtc/PeerConnectionClient.java | 8 +- 7 files changed, 175 insertions(+), 9 deletions(-) diff --git a/talk/app/webrtc/java/jni/classreferenceholder.cc b/talk/app/webrtc/java/jni/classreferenceholder.cc index 0c25575cd..7ff48b972 100644 --- a/talk/app/webrtc/java/jni/classreferenceholder.cc +++ b/talk/app/webrtc/java/jni/classreferenceholder.cc @@ -92,8 +92,11 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) { LoadClass(jni, "org/webrtc/MediaSource$State"); LoadClass(jni, "org/webrtc/MediaStream"); LoadClass(jni, "org/webrtc/MediaStreamTrack$State"); + LoadClass(jni, "org/webrtc/PeerConnection$BundlePolicy"); LoadClass(jni, "org/webrtc/PeerConnection$IceConnectionState"); LoadClass(jni, "org/webrtc/PeerConnection$IceGatheringState"); + LoadClass(jni, "org/webrtc/PeerConnection$IceTransportsType"); + LoadClass(jni, "org/webrtc/PeerConnection$TcpCandidatePolicy"); LoadClass(jni, "org/webrtc/PeerConnection$SignalingState"); LoadClass(jni, "org/webrtc/SessionDescription"); LoadClass(jni, "org/webrtc/SessionDescription$Type"); diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc index 4d13c4184..460ad7efb 100644 --- a/talk/app/webrtc/java/jni/peerconnection_jni.cc +++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc @@ -1164,6 +1164,76 @@ JOW(void, PeerConnectionFactory_nativeSetOptions)( factory->SetOptions(options_to_set); } +static std::string +GetJavaEnumName(JNIEnv* jni, const std::string& className, jobject j_enum) { + jclass enumClass = FindClass(jni, className.c_str()); + jmethodID nameMethod = + GetMethodID(jni, enumClass, "name", "()Ljava/lang/String;"); + jstring name = + reinterpret_cast(jni->CallObjectMethod(j_enum, nameMethod)); + CHECK_EXCEPTION(jni) << "error during CallObjectMethod for " + << className << ".name"; + return JavaToStdString(jni, name); +} + +static PeerConnectionInterface::IceTransportsType +JavaIceTransportsTypeToNativeType(JNIEnv* jni, jobject j_ice_transports_type) { + std::string enum_name = GetJavaEnumName( + jni, "org/webrtc/PeerConnection$IceTransportsType", + j_ice_transports_type); + + if (enum_name == "ALL") + return PeerConnectionInterface::kAll; + + if (enum_name == "RELAY") + return PeerConnectionInterface::kRelay; + + if (enum_name == "NOHOST") + return PeerConnectionInterface::kNoHost; + + if (enum_name == "NONE") + return PeerConnectionInterface::kNone; + + CHECK(false) << "Unexpected IceTransportsType enum_name " << enum_name; + return PeerConnectionInterface::kAll; +} + +static PeerConnectionInterface::BundlePolicy +JavaBundlePolicyToNativeType(JNIEnv* jni, jobject j_bundle_policy) { + std::string enum_name = GetJavaEnumName( + jni, "org/webrtc/PeerConnection$BundlePolicy", + j_bundle_policy); + + if (enum_name == "BALANCED") + return PeerConnectionInterface::kBundlePolicyBalanced; + + if (enum_name == "MAXBUNDLE") + return PeerConnectionInterface::kBundlePolicyMaxBundle; + + if (enum_name == "MAXCOMPAT") + return PeerConnectionInterface::kBundlePolicyMaxCompat; + + CHECK(false) << "Unexpected BundlePolicy enum_name " << enum_name; + return PeerConnectionInterface::kBundlePolicyBalanced; +} + +static PeerConnectionInterface::TcpCandidatePolicy +JavaTcpCandidatePolicyToNativeType( + JNIEnv* jni, jobject j_tcp_candidate_policy) { + std::string enum_name = GetJavaEnumName( + jni, "org/webrtc/PeerConnection$TcpCandidatePolicy", + j_tcp_candidate_policy); + + if (enum_name == "ENABLED") + return PeerConnectionInterface::kTcpCandidatePolicyEnabled; + + if (enum_name == "DISABLED") + return PeerConnectionInterface::kTcpCandidatePolicyDisabled; + + CHECK(false) << "Unexpected TcpCandidatePolicy enum_name " << enum_name; + return PeerConnectionInterface::kTcpCandidatePolicyEnabled; +} + static void JavaIceServersToJsepIceServers( JNIEnv* jni, jobject j_ice_servers, PeerConnectionInterface::IceServers* ice_servers) { @@ -1203,17 +1273,50 @@ static void JavaIceServersToJsepIceServers( } JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnection)( - JNIEnv *jni, jclass, jlong factory, jobject j_ice_servers, + JNIEnv *jni, jclass, jlong factory, jobject j_rtc_config, jobject j_constraints, jlong observer_p) { rtc::scoped_refptr f( reinterpret_cast( factoryFromJava(factory))); - PeerConnectionInterface::IceServers servers; - JavaIceServersToJsepIceServers(jni, j_ice_servers, &servers); + + jclass j_rtc_config_class = GetObjectClass(jni, j_rtc_config); + + jfieldID j_ice_transports_type_id = GetFieldID( + jni, j_rtc_config_class, "iceTransportsType", + "Lorg/webrtc/PeerConnection$IceTransportsType;"); + jobject j_ice_transports_type = GetObjectField( + jni, j_rtc_config, j_ice_transports_type_id); + + jfieldID j_bundle_policy_id = GetFieldID( + jni, j_rtc_config_class, "bundlePolicy", + "Lorg/webrtc/PeerConnection$BundlePolicy;"); + jobject j_bundle_policy = GetObjectField( + jni, j_rtc_config, j_bundle_policy_id); + + jfieldID j_tcp_candidate_policy_id = GetFieldID( + jni, j_rtc_config_class, "tcpCandidatePolicy", + "Lorg/webrtc/PeerConnection$TcpCandidatePolicy;"); + jobject j_tcp_candidate_policy = GetObjectField( + jni, j_rtc_config, j_tcp_candidate_policy_id); + + jfieldID j_ice_servers_id = GetFieldID( + jni, j_rtc_config_class, "iceServers", + "Ljava/util/List;"); + jobject j_ice_servers = GetObjectField(jni, j_rtc_config, j_ice_servers_id); + + PeerConnectionInterface::RTCConfiguration rtc_config; + + rtc_config.type = + JavaIceTransportsTypeToNativeType(jni, j_ice_transports_type); + rtc_config.bundle_policy = JavaBundlePolicyToNativeType(jni, j_bundle_policy); + rtc_config.tcp_candidate_policy = + JavaTcpCandidatePolicyToNativeType(jni, j_tcp_candidate_policy); + JavaIceServersToJsepIceServers(jni, j_ice_servers, &rtc_config.servers); + PCOJava* observer = reinterpret_cast(observer_p); observer->SetConstraints(new ConstraintsWrapper(jni, j_constraints)); rtc::scoped_refptr pc(f->CreatePeerConnection( - servers, observer->constraints(), NULL, NULL, observer)); + rtc_config, observer->constraints(), NULL, NULL, observer)); return (jlong)pc.release(); } diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java index d419f2e59..8fcc975cc 100644 --- a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java @@ -28,6 +28,7 @@ package org.webrtc; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -106,6 +107,36 @@ public class PeerConnection { } } + /** 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.BundlePolicy */ + public enum TcpCandidatePolicy { + ENABLED, DISABLED + }; + + /** Java version of PeerConnectionInterface.RTCConfiguration */ + public static class RTCConfiguration { + public IceTransportsType iceTransportsType; + public List iceServers; + public BundlePolicy bundlePolicy; + public TcpCandidatePolicy tcpCandidatePolicy; + + public RTCConfiguration(List iceServers) { + iceTransportsType = IceTransportsType.ALL; + bundlePolicy = BundlePolicy.BALANCED; + tcpCandidatePolicy = TcpCandidatePolicy.ENABLED; + this.iceServers = iceServers; + } + }; + private final List localStreams; private final long nativePeerConnection; private final long nativeObserver; diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java index 0925290e9..841c681ad 100644 --- a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java @@ -77,7 +77,7 @@ public class PeerConnectionFactory { } public PeerConnection createPeerConnection( - List iceServers, + PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, PeerConnection.Observer observer) { long nativeObserver = nativeCreateObserver(observer); @@ -85,13 +85,22 @@ public class PeerConnectionFactory { return null; } long nativePeerConnection = nativeCreatePeerConnection( - nativeFactory, iceServers, constraints, nativeObserver); + nativeFactory, rtcConfig, constraints, nativeObserver); if (nativePeerConnection == 0) { return null; } return new PeerConnection(nativePeerConnection, nativeObserver); } + public PeerConnection createPeerConnection( + List iceServers, + MediaConstraints constraints, + PeerConnection.Observer observer) { + PeerConnection.RTCConfiguration rtcConfig = + new PeerConnection.RTCConfiguration(iceServers); + return createPeerConnection(rtcConfig, constraints, observer); + } + public MediaStream createLocalMediaStream(String label) { return new MediaStream( nativeCreateLocalMediaStream(nativeFactory, label)); @@ -133,7 +142,7 @@ public class PeerConnectionFactory { PeerConnection.Observer observer); private static native long nativeCreatePeerConnection( - long nativeFactory, List iceServers, + long nativeFactory, PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver); private static native long nativeCreateLocalMediaStream( diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc index 457007a3f..39284c128 100644 --- a/talk/app/webrtc/peerconnection.cc +++ b/talk/app/webrtc/peerconnection.cc @@ -359,6 +359,11 @@ bool PeerConnection::Initialize( portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); } + if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) { + portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP; + LOG(LS_INFO) << "TCP candidates are disabled."; + } + port_allocator_->set_flags(portallocator_flags); // No step delay is used while allocating ports. port_allocator_->set_step_delay(cricket::kMinimumStepDelay); diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h index 6f6eb2482..ed4f5b385 100644 --- a/talk/app/webrtc/peerconnectioninterface.h +++ b/talk/app/webrtc/peerconnectioninterface.h @@ -197,6 +197,11 @@ class PeerConnectionInterface : public rtc::RefCountInterface { kBundlePolicyMaxCompat }; + enum TcpCandidatePolicy { + kTcpCandidatePolicyEnabled, + kTcpCandidatePolicyDisabled + }; + struct RTCConfiguration { // TODO(pthatcher): Rename this ice_transport_type, but update // Chromium at the same time. @@ -205,8 +210,12 @@ class PeerConnectionInterface : public rtc::RefCountInterface { // at the same time. IceServers servers; BundlePolicy bundle_policy; + TcpCandidatePolicy tcp_candidate_policy; - RTCConfiguration() : type(kAll), bundle_policy(kBundlePolicyBalanced) {} + RTCConfiguration() + : type(kAll), + bundle_policy(kBundlePolicyBalanced), + tcp_candidate_policy(kTcpCandidatePolicyEnabled) {} }; struct RTCOfferAnswerOptions { diff --git a/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java b/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java index 76235a8da..967a2ea50 100644 --- a/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java @@ -413,8 +413,14 @@ public class PeerConnectionClient { } queuedRemoteCandidates = new LinkedList(); + PeerConnection.RTCConfiguration rtcConfig = + new PeerConnection.RTCConfiguration(signalingParameters.iceServers); + // TCP candidates are only useful when connecting to a server that supports + // ICE-TCP. + rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED; + peerConnection = factory.createPeerConnection( - signalingParameters.iceServers, pcConstraints, pcObserver); + rtcConfig, pcConstraints, pcObserver); isInitiator = false; // Set default WebRTC tracing and INFO libjingle logging.