diff --git a/api/mediaconstraintsinterface.h b/api/mediaconstraintsinterface.h index ebeec0018f..73e4619bca 100644 --- a/api/mediaconstraintsinterface.h +++ b/api/mediaconstraintsinterface.h @@ -50,9 +50,6 @@ class MediaConstraintsInterface { bool FindFirst(const std::string& key, std::string* value) const; }; - virtual const Constraints& GetMandatory() const = 0; - virtual const Constraints& GetOptional() const = 0; - // Constraint keys used by a local video source. // Specified by draft-alvestrand-constraints-resolution-00b static const char kMinAspectRatio[]; // minAspectRatio @@ -125,9 +122,10 @@ class MediaConstraintsInterface { // stripped by Chrome before passed down to Libjingle. static const char kInternalConstraintPrefix[]; - protected: - // Dtor protected as objects shouldn't be deleted via this interface - virtual ~MediaConstraintsInterface() {} + virtual ~MediaConstraintsInterface() = default; + + virtual const Constraints& GetMandatory() const = 0; + virtual const Constraints& GetOptional() const = 0; }; bool FindConstraint(const MediaConstraintsInterface* constraints, diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 50ae3e7d10..ecf8a1e2c8 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -278,6 +278,7 @@ rtc_static_library("null_media_jni") { generate_jni("generated_peerconnection_jni") { sources = [ + "api/org/webrtc/MediaConstraints.java", "api/org/webrtc/NetworkMonitor.java", "api/org/webrtc/NetworkMonitorAutoDetect.java", ] diff --git a/sdk/android/api/org/webrtc/MediaConstraints.java b/sdk/android/api/org/webrtc/MediaConstraints.java index 259d546812..fc0c9c2c2d 100644 --- a/sdk/android/api/org/webrtc/MediaConstraints.java +++ b/sdk/android/api/org/webrtc/MediaConstraints.java @@ -28,10 +28,12 @@ public class MediaConstraints { this.value = value; } + @CalledByNative("KeyValuePair") public String getKey() { return key; } + @CalledByNative("KeyValuePair") public String getValue() { return value; } @@ -83,4 +85,14 @@ public class MediaConstraints { return "mandatory: " + stringifyKeyValuePairList(mandatory) + ", optional: " + stringifyKeyValuePairList(optional); } + + @CalledByNative + List getMandatory() { + return mandatory; + } + + @CalledByNative + List getOptional() { + return optional; + } } diff --git a/sdk/android/src/jni/pc/mediaconstraints_jni.cc b/sdk/android/src/jni/pc/mediaconstraints_jni.cc index 5f0b1d54cb..b7d05a2428 100644 --- a/sdk/android/src/jni/pc/mediaconstraints_jni.cc +++ b/sdk/android/src/jni/pc/mediaconstraints_jni.cc @@ -10,39 +10,57 @@ #include "sdk/android/src/jni/pc/mediaconstraints_jni.h" +#include "rtc_base/ptr_util.h" +#include "sdk/android/generated_peerconnection_jni/jni/MediaConstraints_jni.h" +#include "sdk/android/src/jni/jni_helpers.h" + namespace webrtc { namespace jni { -MediaConstraintsJni::MediaConstraintsJni(JNIEnv* jni, jobject j_constraints) { - PopulateConstraintsFromJavaPairList(jni, j_constraints, "mandatory", - &mandatory_); - PopulateConstraintsFromJavaPairList(jni, j_constraints, "optional", - &optional_); +namespace { + +// Helper for translating a List> to a Constraints. +MediaConstraintsInterface::Constraints PopulateConstraintsFromJavaPairList( + JNIEnv* env, + jobject j_list) { + MediaConstraintsInterface::Constraints constraints; + for (jobject entry : Iterable(env, j_list)) { + jstring j_key = Java_KeyValuePair_getKey(env, entry); + jstring j_value = Java_KeyValuePair_getValue(env, entry); + constraints.emplace_back(JavaToStdString(env, j_key), + JavaToStdString(env, j_value)); + } + return constraints; } -// static -void MediaConstraintsJni::PopulateConstraintsFromJavaPairList( - JNIEnv* jni, - jobject j_constraints, - const char* field_name, - Constraints* field) { - jfieldID j_id = GetFieldID(jni, GetObjectClass(jni, j_constraints), - field_name, "Ljava/util/List;"); - jobject j_list = GetObjectField(jni, j_constraints, j_id); - for (jobject entry : Iterable(jni, j_list)) { - jmethodID get_key = GetMethodID(jni, GetObjectClass(jni, entry), "getKey", - "()Ljava/lang/String;"); - jstring j_key = - reinterpret_cast(jni->CallObjectMethod(entry, get_key)); - CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; - jmethodID get_value = GetMethodID(jni, GetObjectClass(jni, entry), - "getValue", "()Ljava/lang/String;"); - jstring j_value = - reinterpret_cast(jni->CallObjectMethod(entry, get_value)); - CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; - field->push_back( - Constraint(JavaToStdString(jni, j_key), JavaToStdString(jni, j_value))); - } +// Wrapper for a Java MediaConstraints object. Copies all needed data so when +// the constructor returns the Java object is no longer needed. +class MediaConstraintsJni : public MediaConstraintsInterface { + public: + MediaConstraintsJni(JNIEnv* env, jobject j_constraints) + : mandatory_(PopulateConstraintsFromJavaPairList( + env, + Java_MediaConstraints_getMandatory(env, j_constraints))), + optional_(PopulateConstraintsFromJavaPairList( + env, + Java_MediaConstraints_getOptional(env, j_constraints))) {} + virtual ~MediaConstraintsJni() = default; + + // MediaConstraintsInterface. + const Constraints& GetMandatory() const override { return mandatory_; } + const Constraints& GetOptional() const override { return optional_; } + + private: + const Constraints mandatory_; + const Constraints optional_; +}; + +} // namespace + +std::unique_ptr JavaToNativeMediaConstraints( + JNIEnv* env, + jobject j_constraints) { + return rtc::MakeUnique(env, j_constraints); } } // namespace jni diff --git a/sdk/android/src/jni/pc/mediaconstraints_jni.h b/sdk/android/src/jni/pc/mediaconstraints_jni.h index ec21f43df7..ce7d90dc89 100644 --- a/sdk/android/src/jni/pc/mediaconstraints_jni.h +++ b/sdk/android/src/jni/pc/mediaconstraints_jni.h @@ -11,33 +11,16 @@ #ifndef SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ +#include + #include "api/mediaconstraintsinterface.h" -#include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { namespace jni { -// Wrapper for a Java MediaConstraints object. Copies all needed data so when -// the constructor returns the Java object is no longer needed. -class MediaConstraintsJni : public MediaConstraintsInterface { - public: - MediaConstraintsJni(JNIEnv* jni, jobject j_constraints); - virtual ~MediaConstraintsJni() {} - - // MediaConstraintsInterface. - const Constraints& GetMandatory() const override { return mandatory_; } - const Constraints& GetOptional() const override { return optional_; } - - private: - // Helper for translating a List> to a Constraints. - static void PopulateConstraintsFromJavaPairList(JNIEnv* jni, - jobject j_constraints, - const char* field_name, - Constraints* field); - - Constraints mandatory_; - Constraints optional_; -}; +std::unique_ptr JavaToNativeMediaConstraints( + JNIEnv* env, + jobject j_constraints); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/peerconnection_jni.cc b/sdk/android/src/jni/pc/peerconnection_jni.cc index aea277dfba..8183700514 100644 --- a/sdk/android/src/jni/pc/peerconnection_jni.cc +++ b/sdk/android/src/jni/pc/peerconnection_jni.cc @@ -120,12 +120,12 @@ JNI_FUNCTION_DECLARATION(void, jobject j_pc, jobject j_observer, jobject j_constraints) { - MediaConstraintsJni* constraints = - new MediaConstraintsJni(jni, j_constraints); + std::unique_ptr constraints = + JavaToNativeMediaConstraints(jni, j_constraints); rtc::scoped_refptr observer( new rtc::RefCountedObject(jni, j_observer, - constraints)); - ExtractNativePC(jni, j_pc)->CreateOffer(observer, constraints); + std::move(constraints))); + ExtractNativePC(jni, j_pc)->CreateOffer(observer, observer->constraints()); } JNI_FUNCTION_DECLARATION(void, @@ -134,12 +134,12 @@ JNI_FUNCTION_DECLARATION(void, jobject j_pc, jobject j_observer, jobject j_constraints) { - MediaConstraintsJni* constraints = - new MediaConstraintsJni(jni, j_constraints); + std::unique_ptr constraints = + JavaToNativeMediaConstraints(jni, j_constraints); rtc::scoped_refptr observer( new rtc::RefCountedObject(jni, j_observer, - constraints)); - ExtractNativePC(jni, j_pc)->CreateAnswer(observer, constraints); + std::move(constraints))); + ExtractNativePC(jni, j_pc)->CreateAnswer(observer, observer->constraints()); } JNI_FUNCTION_DECLARATION(void, diff --git a/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc b/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc index e34d1fda97..c42ed547c8 100644 --- a/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc @@ -321,8 +321,8 @@ JNI_FUNCTION_DECLARATION(jlong, jclass, jlong native_factory, jobject j_constraints) { - std::unique_ptr constraints( - new MediaConstraintsJni(jni, j_constraints)); + std::unique_ptr constraints = + JavaToNativeMediaConstraints(jni, j_constraints); rtc::scoped_refptr factory( factoryFromJava(native_factory)); cricket::AudioOptions options; @@ -429,7 +429,7 @@ JNI_FUNCTION_DECLARATION(jlong, PeerConnectionObserverJni* observer = reinterpret_cast(observer_p); - observer->SetConstraints(new MediaConstraintsJni(jni, j_constraints)); + observer->SetConstraints(JavaToNativeMediaConstraints(jni, j_constraints)); CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config); rtc::scoped_refptr pc( f->CreatePeerConnection(rtc_config, nullptr, nullptr, observer)); diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc index 6105255e48..a0eac9185b 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc @@ -337,9 +337,9 @@ void PeerConnectionObserverJni::OnAddTrack( } void PeerConnectionObserverJni::SetConstraints( - MediaConstraintsJni* constraints) { + std::unique_ptr constraints) { RTC_CHECK(!constraints_.get()) << "constraints already set!"; - constraints_.reset(constraints); + constraints_ = std::move(constraints); } void PeerConnectionObserverJni::DisposeRemoteStream( diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.h b/sdk/android/src/jni/pc/peerconnectionobserver_jni.h index a48828b20a..d6fd0f397f 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.h +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.h @@ -52,8 +52,8 @@ class PeerConnectionObserverJni : public PeerConnectionObserver, const std::vector>& streams) override; - void SetConstraints(MediaConstraintsJni* constraints); - const MediaConstraintsJni* constraints() { return constraints_.get(); } + void SetConstraints(std::unique_ptr constraints); + const MediaConstraintsInterface* constraints() { return constraints_.get(); } private: typedef std::map NativeToJavaStreamsMap; @@ -127,7 +127,7 @@ class PeerConnectionObserverJni : public PeerConnectionObserver, // manually deleted upon removal. Use DisposeRemoteStream(). NativeToJavaStreamsMap remote_streams_; NativeToJavaRtpReceiverMap rtp_receivers_; - std::unique_ptr constraints_; + std::unique_ptr constraints_; std::vector> stream_observers_; }; diff --git a/sdk/android/src/jni/pc/sdpobserver_jni.h b/sdk/android/src/jni/pc/sdpobserver_jni.h index b330b69fc8..9b8db6330a 100644 --- a/sdk/android/src/jni/pc/sdpobserver_jni.h +++ b/sdk/android/src/jni/pc/sdpobserver_jni.h @@ -16,7 +16,6 @@ #include "api/peerconnectioninterface.h" #include "sdk/android/src/jni/jni_helpers.h" -#include "sdk/android/src/jni/pc/mediaconstraints_jni.h" namespace webrtc { namespace jni { @@ -29,8 +28,8 @@ class SdpObserverJni : public T { public: SdpObserverJni(JNIEnv* jni, jobject j_observer, - MediaConstraintsJni* constraints) - : constraints_(constraints), + std::unique_ptr constraints) + : constraints_(std::move(constraints)), j_observer_global_(jni, j_observer), j_observer_class_(jni, GetObjectClass(jni, j_observer)) {} @@ -57,6 +56,8 @@ class SdpObserverJni : public T { delete desc; } + MediaConstraintsInterface* constraints() { return constraints_.get(); } + protected: // Common implementation for failure of Set & Create types, distinguished by // |op| being "Set" or "Create". @@ -71,7 +72,7 @@ class SdpObserverJni : public T { JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); } private: - std::unique_ptr constraints_; + std::unique_ptr constraints_; const ScopedGlobalRef j_observer_global_; const ScopedGlobalRef j_observer_class_; }; @@ -81,8 +82,8 @@ class CreateSdpObserverJni public: CreateSdpObserverJni(JNIEnv* jni, jobject j_observer, - MediaConstraintsJni* constraints) - : SdpObserverJni(jni, j_observer, constraints) {} + std::unique_ptr constraints) + : SdpObserverJni(jni, j_observer, std::move(constraints)) {} void OnFailure(const std::string& error) override { ScopedLocalRefFrame local_ref_frame(jni()); @@ -94,8 +95,8 @@ class SetSdpObserverJni : public SdpObserverJni { public: SetSdpObserverJni(JNIEnv* jni, jobject j_observer, - MediaConstraintsJni* constraints) - : SdpObserverJni(jni, j_observer, constraints) {} + std::unique_ptr constraints) + : SdpObserverJni(jni, j_observer, std::move(constraints)) {} void OnFailure(const std::string& error) override { ScopedLocalRefFrame local_ref_frame(jni());