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:

committed by
Commit Bot

parent
f281853c11
commit
3ecdd0f02a
@ -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,
|
||||
|
@ -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",
|
||||
]
|
||||
|
@ -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<KeyValuePair> getMandatory() {
|
||||
return mandatory;
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
List<KeyValuePair> getOptional() {
|
||||
return optional;
|
||||
}
|
||||
}
|
||||
|
@ -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<Pair<String, String>> 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<jstring>(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<jstring>(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<MediaConstraintsInterface> JavaToNativeMediaConstraints(
|
||||
JNIEnv* env,
|
||||
jobject j_constraints) {
|
||||
return rtc::MakeUnique<MediaConstraintsJni>(env, j_constraints);
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
@ -11,33 +11,16 @@
|
||||
#ifndef 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 "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<Pair<String, String>> to a Constraints.
|
||||
static void PopulateConstraintsFromJavaPairList(JNIEnv* jni,
|
||||
jobject j_constraints,
|
||||
const char* field_name,
|
||||
Constraints* field);
|
||||
|
||||
Constraints mandatory_;
|
||||
Constraints optional_;
|
||||
};
|
||||
std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
|
||||
JNIEnv* env,
|
||||
jobject j_constraints);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
@ -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<MediaConstraintsInterface> constraints =
|
||||
JavaToNativeMediaConstraints(jni, j_constraints);
|
||||
rtc::scoped_refptr<CreateSdpObserverJni> observer(
|
||||
new rtc::RefCountedObject<CreateSdpObserverJni>(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<MediaConstraintsInterface> constraints =
|
||||
JavaToNativeMediaConstraints(jni, j_constraints);
|
||||
rtc::scoped_refptr<CreateSdpObserverJni> observer(
|
||||
new rtc::RefCountedObject<CreateSdpObserverJni>(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,
|
||||
|
@ -321,8 +321,8 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
jclass,
|
||||
jlong native_factory,
|
||||
jobject j_constraints) {
|
||||
std::unique_ptr<MediaConstraintsJni> constraints(
|
||||
new MediaConstraintsJni(jni, j_constraints));
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints =
|
||||
JavaToNativeMediaConstraints(jni, j_constraints);
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
|
||||
factoryFromJava(native_factory));
|
||||
cricket::AudioOptions options;
|
||||
@ -429,7 +429,7 @@ JNI_FUNCTION_DECLARATION(jlong,
|
||||
|
||||
PeerConnectionObserverJni* observer =
|
||||
reinterpret_cast<PeerConnectionObserverJni*>(observer_p);
|
||||
observer->SetConstraints(new MediaConstraintsJni(jni, j_constraints));
|
||||
observer->SetConstraints(JavaToNativeMediaConstraints(jni, j_constraints));
|
||||
CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config);
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
f->CreatePeerConnection(rtc_config, nullptr, nullptr, observer));
|
||||
|
@ -337,9 +337,9 @@ void PeerConnectionObserverJni::OnAddTrack(
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::SetConstraints(
|
||||
MediaConstraintsJni* constraints) {
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints) {
|
||||
RTC_CHECK(!constraints_.get()) << "constraints already set!";
|
||||
constraints_.reset(constraints);
|
||||
constraints_ = std::move(constraints);
|
||||
}
|
||||
|
||||
void PeerConnectionObserverJni::DisposeRemoteStream(
|
||||
|
@ -52,8 +52,8 @@ class PeerConnectionObserverJni : public PeerConnectionObserver,
|
||||
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
|
||||
streams) override;
|
||||
|
||||
void SetConstraints(MediaConstraintsJni* constraints);
|
||||
const MediaConstraintsJni* constraints() { return constraints_.get(); }
|
||||
void SetConstraints(std::unique_ptr<MediaConstraintsInterface> constraints);
|
||||
const MediaConstraintsInterface* constraints() { return constraints_.get(); }
|
||||
|
||||
private:
|
||||
typedef std::map<MediaStreamInterface*, jobject> NativeToJavaStreamsMap;
|
||||
@ -127,7 +127,7 @@ class PeerConnectionObserverJni : public PeerConnectionObserver,
|
||||
// manually deleted upon removal. Use DisposeRemoteStream().
|
||||
NativeToJavaStreamsMap remote_streams_;
|
||||
NativeToJavaRtpReceiverMap rtp_receivers_;
|
||||
std::unique_ptr<MediaConstraintsJni> constraints_;
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints_;
|
||||
std::vector<std::unique_ptr<webrtc::MediaStreamObserver>> stream_observers_;
|
||||
};
|
||||
|
||||
|
@ -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<MediaConstraintsInterface> 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<MediaConstraintsJni> constraints_;
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints_;
|
||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||
const ScopedGlobalRef<jclass> 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<MediaConstraintsInterface> 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<SetSessionDescriptionObserver> {
|
||||
public:
|
||||
SetSdpObserverJni(JNIEnv* jni,
|
||||
jobject j_observer,
|
||||
MediaConstraintsJni* constraints)
|
||||
: SdpObserverJni(jni, j_observer, constraints) {}
|
||||
std::unique_ptr<MediaConstraintsInterface> constraints)
|
||||
: SdpObserverJni(jni, j_observer, std::move(constraints)) {}
|
||||
|
||||
void OnFailure(const std::string& error) override {
|
||||
ScopedLocalRefFrame local_ref_frame(jni());
|
||||
|
Reference in New Issue
Block a user