Android: Generate JNI code for MediaConstraints

Also improves ownership model by using std::unique_ptr in a couple of
places instead of raw pointers.

Bug: webrtc:8278
Change-Id: I0429ec3c416b5baa1ffa21dad71e0d64b004c446
Reviewed-on: https://webrtc-review.googlesource.com/25020
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20863}
This commit is contained in:
Magnus Jedvert
2017-11-24 11:21:14 +01:00
committed by Commit Bot
parent f281853c11
commit 3ecdd0f02a
10 changed files with 93 additions and 80 deletions

View File

@ -50,9 +50,6 @@ class MediaConstraintsInterface {
bool FindFirst(const std::string& key, std::string* value) const; 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. // Constraint keys used by a local video source.
// Specified by draft-alvestrand-constraints-resolution-00b // Specified by draft-alvestrand-constraints-resolution-00b
static const char kMinAspectRatio[]; // minAspectRatio static const char kMinAspectRatio[]; // minAspectRatio
@ -125,9 +122,10 @@ class MediaConstraintsInterface {
// stripped by Chrome before passed down to Libjingle. // stripped by Chrome before passed down to Libjingle.
static const char kInternalConstraintPrefix[]; static const char kInternalConstraintPrefix[];
protected: virtual ~MediaConstraintsInterface() = default;
// Dtor protected as objects shouldn't be deleted via this interface
virtual ~MediaConstraintsInterface() {} virtual const Constraints& GetMandatory() const = 0;
virtual const Constraints& GetOptional() const = 0;
}; };
bool FindConstraint(const MediaConstraintsInterface* constraints, bool FindConstraint(const MediaConstraintsInterface* constraints,

View File

@ -278,6 +278,7 @@ rtc_static_library("null_media_jni") {
generate_jni("generated_peerconnection_jni") { generate_jni("generated_peerconnection_jni") {
sources = [ sources = [
"api/org/webrtc/MediaConstraints.java",
"api/org/webrtc/NetworkMonitor.java", "api/org/webrtc/NetworkMonitor.java",
"api/org/webrtc/NetworkMonitorAutoDetect.java", "api/org/webrtc/NetworkMonitorAutoDetect.java",
] ]

View File

@ -28,10 +28,12 @@ public class MediaConstraints {
this.value = value; this.value = value;
} }
@CalledByNative("KeyValuePair")
public String getKey() { public String getKey() {
return key; return key;
} }
@CalledByNative("KeyValuePair")
public String getValue() { public String getValue() {
return value; return value;
} }
@ -83,4 +85,14 @@ public class MediaConstraints {
return "mandatory: " + stringifyKeyValuePairList(mandatory) + ", optional: " return "mandatory: " + stringifyKeyValuePairList(mandatory) + ", optional: "
+ stringifyKeyValuePairList(optional); + stringifyKeyValuePairList(optional);
} }
@CalledByNative
List<KeyValuePair> getMandatory() {
return mandatory;
}
@CalledByNative
List<KeyValuePair> getOptional() {
return optional;
}
} }

View File

@ -10,39 +10,57 @@
#include "sdk/android/src/jni/pc/mediaconstraints_jni.h" #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 webrtc {
namespace jni { namespace jni {
MediaConstraintsJni::MediaConstraintsJni(JNIEnv* jni, jobject j_constraints) { namespace {
PopulateConstraintsFromJavaPairList(jni, j_constraints, "mandatory",
&mandatory_); // Helper for translating a List<Pair<String, String>> to a Constraints.
PopulateConstraintsFromJavaPairList(jni, j_constraints, "optional", MediaConstraintsInterface::Constraints PopulateConstraintsFromJavaPairList(
&optional_); 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 // Wrapper for a Java MediaConstraints object. Copies all needed data so when
void MediaConstraintsJni::PopulateConstraintsFromJavaPairList( // the constructor returns the Java object is no longer needed.
JNIEnv* jni, class MediaConstraintsJni : public MediaConstraintsInterface {
jobject j_constraints, public:
const char* field_name, MediaConstraintsJni(JNIEnv* env, jobject j_constraints)
Constraints* field) { : mandatory_(PopulateConstraintsFromJavaPairList(
jfieldID j_id = GetFieldID(jni, GetObjectClass(jni, j_constraints), env,
field_name, "Ljava/util/List;"); Java_MediaConstraints_getMandatory(env, j_constraints))),
jobject j_list = GetObjectField(jni, j_constraints, j_id); optional_(PopulateConstraintsFromJavaPairList(
for (jobject entry : Iterable(jni, j_list)) { env,
jmethodID get_key = GetMethodID(jni, GetObjectClass(jni, entry), "getKey", Java_MediaConstraints_getOptional(env, j_constraints))) {}
"()Ljava/lang/String;"); virtual ~MediaConstraintsJni() = default;
jstring j_key =
reinterpret_cast<jstring>(jni->CallObjectMethod(entry, get_key)); // MediaConstraintsInterface.
CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; const Constraints& GetMandatory() const override { return mandatory_; }
jmethodID get_value = GetMethodID(jni, GetObjectClass(jni, entry), const Constraints& GetOptional() const override { return optional_; }
"getValue", "()Ljava/lang/String;");
jstring j_value = private:
reinterpret_cast<jstring>(jni->CallObjectMethod(entry, get_value)); const Constraints mandatory_;
CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; const Constraints optional_;
field->push_back( };
Constraint(JavaToStdString(jni, j_key), JavaToStdString(jni, j_value)));
} } // namespace
std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
JNIEnv* env,
jobject j_constraints) {
return rtc::MakeUnique<MediaConstraintsJni>(env, j_constraints);
} }
} // namespace jni } // namespace jni

View File

@ -11,33 +11,16 @@
#ifndef SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_
#define SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_
#include <jni.h>
#include "api/mediaconstraintsinterface.h" #include "api/mediaconstraintsinterface.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
// Wrapper for a Java MediaConstraints object. Copies all needed data so when std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
// the constructor returns the Java object is no longer needed. JNIEnv* env,
class MediaConstraintsJni : public MediaConstraintsInterface { jobject j_constraints);
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<Pair<String, String>> to a Constraints.
static void PopulateConstraintsFromJavaPairList(JNIEnv* jni,
jobject j_constraints,
const char* field_name,
Constraints* field);
Constraints mandatory_;
Constraints optional_;
};
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc

View File

@ -120,12 +120,12 @@ JNI_FUNCTION_DECLARATION(void,
jobject j_pc, jobject j_pc,
jobject j_observer, jobject j_observer,
jobject j_constraints) { jobject j_constraints) {
MediaConstraintsJni* constraints = std::unique_ptr<MediaConstraintsInterface> constraints =
new MediaConstraintsJni(jni, j_constraints); JavaToNativeMediaConstraints(jni, j_constraints);
rtc::scoped_refptr<CreateSdpObserverJni> observer( rtc::scoped_refptr<CreateSdpObserverJni> observer(
new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer, new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
constraints)); std::move(constraints)));
ExtractNativePC(jni, j_pc)->CreateOffer(observer, constraints); ExtractNativePC(jni, j_pc)->CreateOffer(observer, observer->constraints());
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
@ -134,12 +134,12 @@ JNI_FUNCTION_DECLARATION(void,
jobject j_pc, jobject j_pc,
jobject j_observer, jobject j_observer,
jobject j_constraints) { jobject j_constraints) {
MediaConstraintsJni* constraints = std::unique_ptr<MediaConstraintsInterface> constraints =
new MediaConstraintsJni(jni, j_constraints); JavaToNativeMediaConstraints(jni, j_constraints);
rtc::scoped_refptr<CreateSdpObserverJni> observer( rtc::scoped_refptr<CreateSdpObserverJni> observer(
new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer, new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
constraints)); std::move(constraints)));
ExtractNativePC(jni, j_pc)->CreateAnswer(observer, constraints); ExtractNativePC(jni, j_pc)->CreateAnswer(observer, observer->constraints());
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,

View File

@ -321,8 +321,8 @@ JNI_FUNCTION_DECLARATION(jlong,
jclass, jclass,
jlong native_factory, jlong native_factory,
jobject j_constraints) { jobject j_constraints) {
std::unique_ptr<MediaConstraintsJni> constraints( std::unique_ptr<MediaConstraintsInterface> constraints =
new MediaConstraintsJni(jni, j_constraints)); JavaToNativeMediaConstraints(jni, j_constraints);
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory( rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
factoryFromJava(native_factory)); factoryFromJava(native_factory));
cricket::AudioOptions options; cricket::AudioOptions options;
@ -429,7 +429,7 @@ JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionObserverJni* observer = PeerConnectionObserverJni* observer =
reinterpret_cast<PeerConnectionObserverJni*>(observer_p); reinterpret_cast<PeerConnectionObserverJni*>(observer_p);
observer->SetConstraints(new MediaConstraintsJni(jni, j_constraints)); observer->SetConstraints(JavaToNativeMediaConstraints(jni, j_constraints));
CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config); CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config);
rtc::scoped_refptr<PeerConnectionInterface> pc( rtc::scoped_refptr<PeerConnectionInterface> pc(
f->CreatePeerConnection(rtc_config, nullptr, nullptr, observer)); f->CreatePeerConnection(rtc_config, nullptr, nullptr, observer));

View File

@ -337,9 +337,9 @@ void PeerConnectionObserverJni::OnAddTrack(
} }
void PeerConnectionObserverJni::SetConstraints( void PeerConnectionObserverJni::SetConstraints(
MediaConstraintsJni* constraints) { std::unique_ptr<MediaConstraintsInterface> constraints) {
RTC_CHECK(!constraints_.get()) << "constraints already set!"; RTC_CHECK(!constraints_.get()) << "constraints already set!";
constraints_.reset(constraints); constraints_ = std::move(constraints);
} }
void PeerConnectionObserverJni::DisposeRemoteStream( void PeerConnectionObserverJni::DisposeRemoteStream(

View File

@ -52,8 +52,8 @@ class PeerConnectionObserverJni : public PeerConnectionObserver,
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
streams) override; streams) override;
void SetConstraints(MediaConstraintsJni* constraints); void SetConstraints(std::unique_ptr<MediaConstraintsInterface> constraints);
const MediaConstraintsJni* constraints() { return constraints_.get(); } const MediaConstraintsInterface* constraints() { return constraints_.get(); }
private: private:
typedef std::map<MediaStreamInterface*, jobject> NativeToJavaStreamsMap; typedef std::map<MediaStreamInterface*, jobject> NativeToJavaStreamsMap;
@ -127,7 +127,7 @@ class PeerConnectionObserverJni : public PeerConnectionObserver,
// manually deleted upon removal. Use DisposeRemoteStream(). // manually deleted upon removal. Use DisposeRemoteStream().
NativeToJavaStreamsMap remote_streams_; NativeToJavaStreamsMap remote_streams_;
NativeToJavaRtpReceiverMap rtp_receivers_; NativeToJavaRtpReceiverMap rtp_receivers_;
std::unique_ptr<MediaConstraintsJni> constraints_; std::unique_ptr<MediaConstraintsInterface> constraints_;
std::vector<std::unique_ptr<webrtc::MediaStreamObserver>> stream_observers_; std::vector<std::unique_ptr<webrtc::MediaStreamObserver>> stream_observers_;
}; };

View File

@ -16,7 +16,6 @@
#include "api/peerconnectioninterface.h" #include "api/peerconnectioninterface.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/mediaconstraints_jni.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
@ -29,8 +28,8 @@ class SdpObserverJni : public T {
public: public:
SdpObserverJni(JNIEnv* jni, SdpObserverJni(JNIEnv* jni,
jobject j_observer, jobject j_observer,
MediaConstraintsJni* constraints) std::unique_ptr<MediaConstraintsInterface> constraints)
: constraints_(constraints), : constraints_(std::move(constraints)),
j_observer_global_(jni, j_observer), j_observer_global_(jni, j_observer),
j_observer_class_(jni, GetObjectClass(jni, j_observer)) {} j_observer_class_(jni, GetObjectClass(jni, j_observer)) {}
@ -57,6 +56,8 @@ class SdpObserverJni : public T {
delete desc; delete desc;
} }
MediaConstraintsInterface* constraints() { return constraints_.get(); }
protected: protected:
// Common implementation for failure of Set & Create types, distinguished by // Common implementation for failure of Set & Create types, distinguished by
// |op| being "Set" or "Create". // |op| being "Set" or "Create".
@ -71,7 +72,7 @@ class SdpObserverJni : public T {
JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); } JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
private: private:
std::unique_ptr<MediaConstraintsJni> constraints_; std::unique_ptr<MediaConstraintsInterface> constraints_;
const ScopedGlobalRef<jobject> j_observer_global_; const ScopedGlobalRef<jobject> j_observer_global_;
const ScopedGlobalRef<jclass> j_observer_class_; const ScopedGlobalRef<jclass> j_observer_class_;
}; };
@ -81,8 +82,8 @@ class CreateSdpObserverJni
public: public:
CreateSdpObserverJni(JNIEnv* jni, CreateSdpObserverJni(JNIEnv* jni,
jobject j_observer, jobject j_observer,
MediaConstraintsJni* constraints) std::unique_ptr<MediaConstraintsInterface> constraints)
: SdpObserverJni(jni, j_observer, constraints) {} : SdpObserverJni(jni, j_observer, std::move(constraints)) {}
void OnFailure(const std::string& error) override { void OnFailure(const std::string& error) override {
ScopedLocalRefFrame local_ref_frame(jni()); ScopedLocalRefFrame local_ref_frame(jni());
@ -94,8 +95,8 @@ class SetSdpObserverJni : public SdpObserverJni<SetSessionDescriptionObserver> {
public: public:
SetSdpObserverJni(JNIEnv* jni, SetSdpObserverJni(JNIEnv* jni,
jobject j_observer, jobject j_observer,
MediaConstraintsJni* constraints) std::unique_ptr<MediaConstraintsInterface> constraints)
: SdpObserverJni(jni, j_observer, constraints) {} : SdpObserverJni(jni, j_observer, std::move(constraints)) {}
void OnFailure(const std::string& error) override { void OnFailure(const std::string& error) override {
ScopedLocalRefFrame local_ref_frame(jni()); ScopedLocalRefFrame local_ref_frame(jni());