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;
};
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,

View File

@ -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",
]

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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));

View File

@ -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(

View File

@ -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_;
};

View File

@ -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());