Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(515)

Unified Diff: webrtc/sdk/android/src/jni/peerconnection_jni.cc

Issue 2807933003: Add Java binding for new getStats implementation. (Closed)
Patch Set: Fixing copyright year. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/sdk/android/src/jni/peerconnection_jni.cc
diff --git a/webrtc/sdk/android/src/jni/peerconnection_jni.cc b/webrtc/sdk/android/src/jni/peerconnection_jni.cc
index 75b1bad20256dcafd288b6a953d8e686c8a216ca..d35813b540b60443e0d298f99ae1450b6571e0be 100644
--- a/webrtc/sdk/android/src/jni/peerconnection_jni.cc
+++ b/webrtc/sdk/android/src/jni/peerconnection_jni.cc
@@ -839,6 +839,275 @@ class StatsObserverWrapper : public StatsObserver {
const jmethodID j_value_ctor_;
};
+// Adapter for a Java RTCStatsCollectorCallback presenting a C++
+// RTCStatsCollectorCallback and dispatching the callback from C++ back to
+// Java.
+class RTCStatsCollectorCallbackWrapper
+ : public webrtc::RTCStatsCollectorCallback {
+ public:
+ RTCStatsCollectorCallbackWrapper(JNIEnv* jni, jobject j_callback)
+ : j_callback_global_(jni, j_callback),
+ j_callback_class_(jni, GetObjectClass(jni, j_callback)),
+ j_stats_report_class_(jni, FindClass(jni, "org/webrtc/RTCStatsReport")),
+ j_stats_report_ctor_(GetMethodID(jni,
+ *j_stats_report_class_,
+ "<init>",
+ "(JLjava/util/SortedMap;)V")),
+ j_stats_class_(jni, FindClass(jni, "org/webrtc/RTCStats")),
+ j_stats_ctor_(GetMethodID(
+ jni,
+ *j_stats_class_,
+ "<init>",
+ "(JLjava/lang/String;Ljava/lang/String;Ljava/util/SortedMap;)V")),
+ j_tree_map_class_(jni, FindClass(jni, "java/util/TreeMap")),
+ j_tree_map_ctor_(GetMethodID(jni, *j_tree_map_class_, "<init>", "()V")),
+ j_tree_map_put_(GetMethodID(
+ jni,
+ *j_tree_map_class_,
+ "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")),
+ j_boolean_class_(jni, FindClass(jni, "java/lang/Boolean")),
+ j_boolean_ctor_(GetMethodID(jni, *j_boolean_class_, "<init>", "(Z)V")),
+ j_integer_class_(jni, FindClass(jni, "java/lang/Integer")),
+ j_integer_ctor_(GetMethodID(jni, *j_integer_class_, "<init>", "(I)V")),
+ j_long_class_(jni, FindClass(jni, "java/lang/Long")),
+ j_long_ctor_(GetMethodID(jni, *j_long_class_, "<init>", "(J)V")),
+ j_big_integer_class_(jni, FindClass(jni, "java/math/BigInteger")),
+ j_big_integer_ctor_(GetMethodID(jni,
+ *j_big_integer_class_,
+ "<init>",
+ "(Ljava/lang/String;)V")),
+ j_double_class_(jni, FindClass(jni, "java/lang/Double")),
+ j_double_ctor_(GetMethodID(jni, *j_double_class_, "<init>", "(D)V")),
+ j_string_class_(jni, FindClass(jni, "java/lang/String")) {}
+
+ void OnStatsDelivered(
+ const rtc::scoped_refptr<const webrtc::RTCStatsReport>& report) override {
+ JNIEnv* jni = AttachCurrentThreadIfNeeded();
+ ScopedLocalRefFrame local_ref_frame(jni);
+ jobject j_report = ReportToJava(jni, report);
+ jmethodID m = GetMethodID(jni, *j_callback_class_, "onStatsDelivered",
+ "(Lorg/webrtc/RTCStatsReport;)V");
+ jni->CallVoidMethod(*j_callback_global_, m, j_report);
+ CHECK_EXCEPTION(jni) << "error during CallVoidMethod";
+ }
+
+ private:
+ jobject ReportToJava(
+ JNIEnv* jni,
+ const rtc::scoped_refptr<const webrtc::RTCStatsReport>& report) {
+ jobject j_stats_map = jni->NewObject(*j_tree_map_class_, j_tree_map_ctor_);
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ for (const webrtc::RTCStats& stats : *report) {
+ ScopedLocalRefFrame local_ref_frame(jni);
hbos 2017/04/10 10:19:42 If we should use ScopedLocalRefFrame for each scop
Taylor Brandstetter 2017/04/10 23:59:33 Confession: I was just copying the pattern of the
hbos 2017/04/11 09:36:13 Confession: I was just guessing how this JNI stuff
+ jstring j_id = JavaStringFromStdString(jni, stats.id());
+ jobject j_stats = StatsToJava(jni, stats);
+ jni->CallObjectMethod(j_stats_map, j_tree_map_put_, j_id, j_stats);
+ CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
+ }
+ jobject j_report =
+ jni->NewObject(*j_stats_report_class_, j_stats_report_ctor_,
+ report->timestamp_us(), j_stats_map);
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return j_report;
+ }
+
+ jobject StatsToJava(JNIEnv* jni, const webrtc::RTCStats& stats) {
+ jstring j_type = JavaStringFromStdString(jni, stats.type());
+ jstring j_id = JavaStringFromStdString(jni, stats.id());
+ jobject j_members = jni->NewObject(*j_tree_map_class_, j_tree_map_ctor_);
+ for (const webrtc::RTCStatsMemberInterface* member : stats.Members()) {
+ if (!member->is_defined()) {
+ continue;
+ }
+ ScopedLocalRefFrame local_ref_frame(jni);
+ jstring j_name = JavaStringFromStdString(jni, member->name());
+ jobject j_member = MemberToJava(jni, member);
+ jni->CallObjectMethod(j_members, j_tree_map_put_, j_name, j_member);
+ CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
+ }
+ jobject j_stats =
+ jni->NewObject(*j_stats_class_, j_stats_ctor_, stats.timestamp_us(),
+ j_type, j_id, j_members);
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return j_stats;
+ }
+
+ jobject MemberToJava(JNIEnv* jni,
+ const webrtc::RTCStatsMemberInterface* member) {
+ switch (member->type()) {
+ case webrtc::RTCStatsMemberInterface::kBool: {
+ jobject value =
+ jni->NewObject(*j_boolean_class_, j_boolean_ctor_,
+ *member->cast_to<webrtc::RTCStatsMember<bool>>());
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return value;
+ }
+ case webrtc::RTCStatsMemberInterface::kInt32: {
+ jobject value =
+ jni->NewObject(*j_integer_class_, j_integer_ctor_,
+ *member->cast_to<webrtc::RTCStatsMember<int32_t>>());
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return value;
+ }
+ case webrtc::RTCStatsMemberInterface::kUint32: {
+ jobject value = jni->NewObject(
+ *j_long_class_, j_long_ctor_,
+ (jlong)*member->cast_to<webrtc::RTCStatsMember<uint32_t>>());
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return value;
+ }
+ case webrtc::RTCStatsMemberInterface::kInt64: {
+ jobject value =
+ jni->NewObject(*j_long_class_, j_long_ctor_,
+ *member->cast_to<webrtc::RTCStatsMember<int64_t>>());
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return value;
+ }
+ case webrtc::RTCStatsMemberInterface::kUint64: {
+ jobject value = jni->NewObject(
+ *j_big_integer_class_, j_big_integer_ctor_,
+ JavaStringFromStdString(jni, member->ValueToString()));
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return value;
+ }
+ case webrtc::RTCStatsMemberInterface::kDouble: {
+ jobject value =
+ jni->NewObject(*j_double_class_, j_double_ctor_,
+ *member->cast_to<webrtc::RTCStatsMember<double>>());
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ return value;
+ }
+ case webrtc::RTCStatsMemberInterface::kString: {
+ return JavaStringFromStdString(
+ jni, *member->cast_to<webrtc::RTCStatsMember<std::string>>());
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceBool: {
+ const std::vector<bool>& values =
+ *member->cast_to<webrtc::RTCStatsMember<std::vector<bool>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_boolean_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jobject value =
+ jni->NewObject(*j_boolean_class_, j_boolean_ctor_, values[i]);
+ jni->SetObjectArrayElement(j_values, i, value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceInt32: {
+ const std::vector<int32_t>& values =
+ *member->cast_to<webrtc::RTCStatsMember<std::vector<int32_t>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_integer_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jobject value =
+ jni->NewObject(*j_integer_class_, j_integer_ctor_, values[i]);
+ jni->SetObjectArrayElement(j_values, i, value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceUint32: {
+ const std::vector<uint32_t>& values =
+ *member->cast_to<webrtc::RTCStatsMember<std::vector<uint32_t>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_long_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jobject value =
+ jni->NewObject(*j_long_class_, j_long_ctor_, values[i]);
+ jni->SetObjectArrayElement(j_values, i, value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceInt64: {
+ const std::vector<int64_t>& values =
+ *member->cast_to<webrtc::RTCStatsMember<std::vector<int64_t>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_long_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jobject value =
+ jni->NewObject(*j_long_class_, j_long_ctor_, values[i]);
+ jni->SetObjectArrayElement(j_values, i, value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceUint64: {
+ const std::vector<uint64_t>& values =
+ *member->cast_to<webrtc::RTCStatsMember<std::vector<uint64_t>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_big_integer_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jobject value = jni->NewObject(
+ *j_big_integer_class_, j_big_integer_ctor_,
+ JavaStringFromStdString(jni, rtc::ToString(values[i])));
+ jni->SetObjectArrayElement(j_values, i, value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceDouble: {
+ const std::vector<double>& values =
+ *member->cast_to<webrtc::RTCStatsMember<std::vector<double>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_double_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jobject value =
+ jni->NewObject(*j_double_class_, j_double_ctor_, values[i]);
+ jni->SetObjectArrayElement(j_values, i, value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ case webrtc::RTCStatsMemberInterface::kSequenceString: {
+ const std::vector<std::string>& values =
+ *member
+ ->cast_to<webrtc::RTCStatsMember<std::vector<std::string>>>();
+ jobjectArray j_values =
+ jni->NewObjectArray(values.size(), *j_string_class_, nullptr);
+ CHECK_EXCEPTION(jni) << "error during NewObjectArray";
+ for (size_t i = 0; i < values.size(); ++i) {
+ jni->SetObjectArrayElement(j_values, i,
+ JavaStringFromStdString(jni, values[i]));
+ CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
+ }
+ return j_values;
+ }
+ }
+ RTC_NOTREACHED();
+ return nullptr;
+ }
+
+ const ScopedGlobalRef<jobject> j_callback_global_;
+ const ScopedGlobalRef<jclass> j_callback_class_;
+ const ScopedGlobalRef<jclass> j_stats_report_class_;
+ const jmethodID j_stats_report_ctor_;
+ const ScopedGlobalRef<jclass> j_stats_class_;
+ const jmethodID j_stats_ctor_;
+ const ScopedGlobalRef<jclass> j_tree_map_class_;
+ const jmethodID j_tree_map_ctor_;
+ const jmethodID j_tree_map_put_;
+ const ScopedGlobalRef<jclass> j_boolean_class_;
+ const jmethodID j_boolean_ctor_;
+ const ScopedGlobalRef<jclass> j_integer_class_;
+ const jmethodID j_integer_ctor_;
+ const ScopedGlobalRef<jclass> j_long_class_;
+ const jmethodID j_long_ctor_;
+ const ScopedGlobalRef<jclass> j_big_integer_class_;
+ const jmethodID j_big_integer_ctor_;
+ const ScopedGlobalRef<jclass> j_double_class_;
+ const jmethodID j_double_ctor_;
+ const ScopedGlobalRef<jclass> j_string_class_;
+};
+
// Wrapper dispatching rtc::VideoSinkInterface to a Java VideoRenderer
// instance.
class JavaVideoRendererWrapper
@@ -2121,8 +2390,8 @@ JOW(jobject, PeerConnection_nativeGetReceivers)(JNIEnv* jni, jobject j_pc) {
return j_receivers;
}
-JOW(bool, PeerConnection_nativeGetStats)(
- JNIEnv* jni, jobject j_pc, jobject j_observer, jlong native_track) {
+JOW(bool, PeerConnection_nativeOldGetStats)
+(JNIEnv* jni, jobject j_pc, jobject j_observer, jlong native_track) {
rtc::scoped_refptr<StatsObserverWrapper> observer(
new rtc::RefCountedObject<StatsObserverWrapper>(jni, j_observer));
return ExtractNativePC(jni, j_pc)->GetStats(
@@ -2131,6 +2400,14 @@ JOW(bool, PeerConnection_nativeGetStats)(
PeerConnectionInterface::kStatsOutputLevelStandard);
}
+JOW(void, PeerConnection_nativeNewGetStats)
+(JNIEnv* jni, jobject j_pc, jobject j_callback) {
+ rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper> callback(
+ new rtc::RefCountedObject<RTCStatsCollectorCallbackWrapper>(jni,
+ j_callback));
+ ExtractNativePC(jni, j_pc)->GetStats(callback);
+}
+
JOW(bool, PeerConnection_nativeStartRtcEventLog)(
JNIEnv* jni, jobject j_pc, int file_descriptor, int max_size_bytes) {
return ExtractNativePC(jni, j_pc)->StartRtcEventLog(file_descriptor,

Powered by Google App Engine
This is Rietveld 408576698