diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index c7738cc5e2..c7427da178 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -42,7 +42,14 @@ generate_jni("generated_base_jni") { } generate_jar_jni("generated_external_classes_jni") { - classes = [ "java/lang/Integer.class" ] + classes = [ + "java/lang/Integer.class", + "java/lang/Double.class", + "java/lang/Long.class", + "java/lang/Boolean.class", + "java/math/BigInteger.class", + "java/lang/String.class", + ] jni_package = "" jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" } @@ -294,6 +301,8 @@ generate_jni("generated_peerconnection_jni") { "api/org/webrtc/RTCStats.java", "api/org/webrtc/RTCStatsCollectorCallback.java", "api/org/webrtc/RTCStatsReport.java", + "api/org/webrtc/StatsObserver.java", + "api/org/webrtc/StatsReport.java", ] jni_package = "" jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" @@ -357,6 +366,7 @@ rtc_static_library("peerconnection_jni") { deps = [ ":base_jni", + ":generated_external_classes_jni", ":generated_peerconnection_jni", "../..:webrtc_common", "../../api/video_codecs:video_codecs_api", diff --git a/sdk/android/api/org/webrtc/IceCandidate.java b/sdk/android/api/org/webrtc/IceCandidate.java index 51865e9f16..eebc9d9fa6 100644 --- a/sdk/android/api/org/webrtc/IceCandidate.java +++ b/sdk/android/api/org/webrtc/IceCandidate.java @@ -49,9 +49,4 @@ public class IceCandidate { String getSdp() { return sdp; } - - @CalledByNative - static IceCandidate[] createArray(int size) { - return new IceCandidate[size]; - } } diff --git a/sdk/android/api/org/webrtc/StatsObserver.java b/sdk/android/api/org/webrtc/StatsObserver.java index b1ad0dea21..b9984c18db 100644 --- a/sdk/android/api/org/webrtc/StatsObserver.java +++ b/sdk/android/api/org/webrtc/StatsObserver.java @@ -13,5 +13,5 @@ package org.webrtc; /** Interface for observing Stats reports (see webrtc::StatsObservers). */ public interface StatsObserver { /** Called when the reports are ready.*/ - public void onComplete(StatsReport[] reports); + @CalledByNative public void onComplete(StatsReport[] reports); } diff --git a/sdk/android/api/org/webrtc/StatsReport.java b/sdk/android/api/org/webrtc/StatsReport.java index b5396fc860..b8f1cf87fe 100644 --- a/sdk/android/api/org/webrtc/StatsReport.java +++ b/sdk/android/api/org/webrtc/StatsReport.java @@ -17,6 +17,7 @@ public class StatsReport { public final String name; public final String value; + @CalledByNative("Value") public Value(String name, String value) { this.name = name; this.value = value; @@ -36,6 +37,7 @@ public class StatsReport { public final double timestamp; public final Value[] values; + @CalledByNative public StatsReport(String id, String type, double timestamp, Value[] values) { this.id = id; this.type = type; diff --git a/sdk/android/src/jni/classreferenceholder.cc b/sdk/android/src/jni/classreferenceholder.cc index a175a0fbb9..b1f8fdaaf6 100644 --- a/sdk/android/src/jni/classreferenceholder.cc +++ b/sdk/android/src/jni/classreferenceholder.cc @@ -51,11 +51,7 @@ void FreeGlobalClassReferenceHolder() { ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) { LoadClass(jni, "android/graphics/SurfaceTexture"); - LoadClass(jni, "java/lang/Boolean"); - LoadClass(jni, "java/lang/Double"); - LoadClass(jni, "java/lang/Long"); LoadClass(jni, "java/lang/String"); - LoadClass(jni, "java/math/BigInteger"); LoadClass(jni, "java/nio/ByteBuffer"); LoadClass(jni, "java/util/ArrayList"); LoadClass(jni, "java/util/LinkedHashMap"); diff --git a/sdk/android/src/jni/encodedimage.cc b/sdk/android/src/jni/encodedimage.cc index 966ef93d39..81c5caa761 100644 --- a/sdk/android/src/jni/encodedimage.cc +++ b/sdk/android/src/jni/encodedimage.cc @@ -13,6 +13,7 @@ #include "common_video/include/video_frame.h" #include "rtc_base/timeutils.h" #include "sdk/android/generated_video_jni/jni/EncodedImage_jni.h" +#include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { namespace jni { @@ -24,12 +25,21 @@ jobject NativeToJavaFrameType(JNIEnv* env, FrameType frame_type) { jobject NativeToJavaEncodedImage(JNIEnv* jni, const EncodedImage& image) { jobject buffer = jni->NewDirectByteBuffer(image._buffer, image._length); jobject frame_type = NativeToJavaFrameType(jni, image._frameType); - jobject qp = (image.qp_ == -1) ? nullptr : JavaIntegerFromInt(jni, image.qp_); + jobject qp = + (image.qp_ == -1) ? nullptr : NativeToJavaInteger(jni, image.qp_); return Java_EncodedImage_Constructor( jni, buffer, image._encodedWidth, image._encodedHeight, image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type, static_cast(image.rotation_), image._completeFrame, qp); } +jobjectArray NativeToJavaFrameTypeArray( + JNIEnv* env, + const std::vector& frame_types) { + return NativeToJavaObjectArray( + env, frame_types, org_webrtc_EncodedImage_00024FrameType_clazz(env), + &NativeToJavaFrameType); +} + } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/encodedimage.h b/sdk/android/src/jni/encodedimage.h index a84b91e3c7..563b0d0095 100644 --- a/sdk/android/src/jni/encodedimage.h +++ b/sdk/android/src/jni/encodedimage.h @@ -13,7 +13,6 @@ #include -#include "api/video/video_rotation.h" #include "common_types.h" // NOLINT(build/include) namespace webrtc { @@ -24,6 +23,9 @@ namespace jni { jobject NativeToJavaFrameType(JNIEnv* env, FrameType frame_type); jobject NativeToJavaEncodedImage(JNIEnv* jni, const EncodedImage& image); +jobjectArray NativeToJavaFrameTypeArray( + JNIEnv* env, + const std::vector& frame_types); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/jni_helpers.cc b/sdk/android/src/jni/jni_helpers.cc index fa8adc307a..694ebead2c 100644 --- a/sdk/android/src/jni/jni_helpers.cc +++ b/sdk/android/src/jni/jni_helpers.cc @@ -15,7 +15,10 @@ #include #include +#include "sdk/android/generated_external_classes_jni/jni/Boolean_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Double_jni.h" #include "sdk/android/generated_external_classes_jni/jni/Integer_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Long_jni.h" #include "sdk/android/src/jni/class_loader.h" #include "sdk/android/src/jni/classreferenceholder.h" @@ -233,13 +236,6 @@ bool IsNull(JNIEnv* jni, jobject obj) { return jni->IsSameObject(obj, nullptr); } -// Given a UTF-8 encoded |native| string return a new (UTF-16) jstring. -jstring JavaStringFromStdString(JNIEnv* jni, const std::string& native) { - jstring jstr = jni->NewStringUTF(native.c_str()); - CHECK_EXCEPTION(jni) << "error during NewStringUTF"; - return jstr; -} - // Given a jstring, reinterprets it to a new native string. std::string JavaToStdString(JNIEnv* jni, const jstring& j_string) { // Invoke String.getBytes(String charsetName) method to convert |j_string| @@ -275,21 +271,39 @@ std::vector JavaToStdVectorStrings(JNIEnv* jni, jobject list) { return converted_list; } -rtc::Optional JavaIntegerToOptionalInt(JNIEnv* jni, jobject integer) { +rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer) { if (IsNull(jni, integer)) return rtc::nullopt; return JNI_Integer::Java_Integer_intValue(jni, integer); } -jobject JavaIntegerFromOptionalInt(JNIEnv* jni, - const rtc::Optional& optional_int) { - return optional_int ? JavaIntegerFromInt(jni, *optional_int) : nullptr; +jobject NativeToJavaBoolean(JNIEnv* env, bool b) { + return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b); } -jobject JavaIntegerFromInt(JNIEnv* jni, int32_t i) { +jobject NativeToJavaInteger(JNIEnv* jni, int32_t i) { return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i); } +jobject NativeToJavaLong(JNIEnv* env, int64_t u) { + return JNI_Long::Java_Long_ConstructorJLLO_J(env, u); +} + +jobject NativeToJavaDouble(JNIEnv* env, double d) { + return JNI_Double::Java_Double_ConstructorJLD_D(env, d); +} + +jstring NativeToJavaString(JNIEnv* jni, const std::string& native) { + jstring jstr = jni->NewStringUTF(native.c_str()); + CHECK_EXCEPTION(jni) << "error during NewStringUTF"; + return jstr; +} + +jobject NativeToJavaInteger(JNIEnv* jni, + const rtc::Optional& optional_int) { + return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr; +} + // Return the (singleton) Java Enum object corresponding to |index|; jobject JavaEnumFromIndex(JNIEnv* jni, jclass state_class, const std::string& state_class_name, int index) { @@ -453,5 +467,39 @@ bool Iterable::Iterator::AtEnd() const { return jni_ == nullptr || IsNull(jni_, iterator_); } +jobjectArray NativeToJavaIntegerArray(JNIEnv* env, + const std::vector& container) { + jobject (*convert_function)(JNIEnv*, int32_t) = &NativeToJavaInteger; + return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env), + convert_function); +} + +jobjectArray NativeToJavaBooleanArray(JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env), + &NativeToJavaBoolean); +} + +jobjectArray NativeToJavaDoubleArray(JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env), + &NativeToJavaDouble); +} + +jobjectArray NativeToJavaLongArray(JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env), + &NativeToJavaLong); +} + +jobjectArray NativeToJavaStringArray( + JNIEnv* env, + const std::vector& container) { + // TODO(magjed): Remove this class when we can generate it from String.class + // directly (the script currently chokes on that class). + return NativeToJavaObjectArray( + env, container, FindClass(env, "java/lang/String"), &NativeToJavaString); +} + } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/jni_helpers.h b/sdk/android/src/jni/jni_helpers.h index e18edc2d40..bfef3a8802 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -98,9 +98,6 @@ bool GetBooleanField(JNIEnv* jni, jobject object, jfieldID id); // Returns true if |obj| == null in Java. bool IsNull(JNIEnv* jni, jobject obj); -// Given a UTF-8 encoded |native| string return a new (UTF-16) jstring. -jstring JavaStringFromStdString(JNIEnv* jni, const std::string& native); - // Given a (UTF-16) jstring return a new UTF-8 native string. std::string JavaToStdString(JNIEnv* jni, const jstring& j_string); @@ -108,12 +105,16 @@ std::string JavaToStdString(JNIEnv* jni, const jstring& j_string); // return a new vector of UTF-8 native strings. std::vector JavaToStdVectorStrings(JNIEnv* jni, jobject list); -rtc::Optional JavaIntegerToOptionalInt(JNIEnv* jni, jobject integer); +rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer); -jobject JavaIntegerFromOptionalInt(JNIEnv* jni, - const rtc::Optional& optional_int); - -jobject JavaIntegerFromInt(JNIEnv* jni, int32_t i); +jobject NativeToJavaBoolean(JNIEnv* env, bool b); +jobject NativeToJavaInteger(JNIEnv* jni, int32_t i); +jobject NativeToJavaLong(JNIEnv* env, int64_t u); +jobject NativeToJavaDouble(JNIEnv* env, double d); +// Given a UTF-8 encoded |native| string return a new (UTF-16) jstring. +jstring NativeToJavaString(JNIEnv* jni, const std::string& native); +jobject NativeToJavaInteger(JNIEnv* jni, + const rtc::Optional& optional_int); // Return the (singleton) Java Enum object corresponding to |index|; jobject JavaEnumFromIndex(JNIEnv* jni, jclass state_class, @@ -228,6 +229,37 @@ class Iterable { RTC_DISALLOW_COPY_AND_ASSIGN(Iterable); }; +// Helper function for converting std::vector into a Java array. +template +jobjectArray NativeToJavaObjectArray(JNIEnv* env, + const std::vector& container, + jclass clazz, + Convert convert) { + jobjectArray j_container = + env->NewObjectArray(container.size(), clazz, nullptr); + int i = 0; + for (const T& element : container) { + jobject j_element = convert(env, element); + env->SetObjectArrayElement(j_container, i, j_element); + // Delete local ref immediately since we might create a lot of local + // references in this loop. + env->DeleteLocalRef(j_element); + ++i; + } + return j_container; +} + +jobjectArray NativeToJavaIntegerArray(JNIEnv* env, + const std::vector& container); +jobjectArray NativeToJavaBooleanArray(JNIEnv* env, + const std::vector& container); +jobjectArray NativeToJavaLongArray(JNIEnv* env, + const std::vector& container); +jobjectArray NativeToJavaDoubleArray(JNIEnv* env, + const std::vector& container); +jobjectArray NativeToJavaStringArray(JNIEnv* env, + const std::vector& container); + } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/datachannel.cc b/sdk/android/src/jni/pc/datachannel.cc index 758e4b90e7..c4be431827 100644 --- a/sdk/android/src/jni/pc/datachannel.cc +++ b/sdk/android/src/jni/pc/datachannel.cc @@ -111,7 +111,7 @@ JNI_FUNCTION_DECLARATION(jstring, DataChannel_label, JNIEnv* jni, jobject j_dc) { - return JavaStringFromStdString(jni, ExtractNativeDC(jni, j_dc)->label()); + return NativeToJavaString(jni, ExtractNativeDC(jni, j_dc)->label()); } JNI_FUNCTION_DECLARATION(jint, DataChannel_id, JNIEnv* jni, jobject j_dc) { diff --git a/sdk/android/src/jni/pc/dtmfsender_jni.cc b/sdk/android/src/jni/pc/dtmfsender_jni.cc index a21314a112..c8d5493d7e 100644 --- a/sdk/android/src/jni/pc/dtmfsender_jni.cc +++ b/sdk/android/src/jni/pc/dtmfsender_jni.cc @@ -40,7 +40,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_dtmf_sender_pointer) { - return JavaStringFromStdString( + return NativeToJavaString( jni, reinterpret_cast(j_dtmf_sender_pointer)->tones()); } diff --git a/sdk/android/src/jni/pc/java_native_conversion.cc b/sdk/android/src/jni/pc/java_native_conversion.cc index ee4640b106..3f0e2e1e1b 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.cc +++ b/sdk/android/src/jni/pc/java_native_conversion.cc @@ -22,15 +22,14 @@ namespace jni { namespace { -jobject NativeToJavaCandidate(JNIEnv* env, - const std::string& sdp_mid, - int sdp_mline_index, - const std::string& sdp, - const std::string server_url) { +jobject CreateJavaIceCandidate(JNIEnv* env, + const std::string& sdp_mid, + int sdp_mline_index, + const std::string& sdp, + const std::string server_url) { return Java_IceCandidate_Constructor( - env, JavaStringFromStdString(env, sdp_mid), sdp_mline_index, - JavaStringFromStdString(env, sdp), - JavaStringFromStdString(env, server_url)); + env, NativeToJavaString(env, sdp_mid), sdp_mline_index, + NativeToJavaString(env, sdp), NativeToJavaString(env, server_url)); } } // namespace @@ -61,31 +60,26 @@ jobject NativeToJavaCandidate(JNIEnv* env, std::string sdp = SdpSerializeCandidate(candidate); RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate"; // sdp_mline_index is not used, pass an invalid value -1. - return NativeToJavaCandidate(env, candidate.transport_name(), - -1 /* sdp_mline_index */, sdp, - "" /* server_url */); + return CreateJavaIceCandidate(env, candidate.transport_name(), + -1 /* sdp_mline_index */, sdp, + "" /* server_url */); } -jobject NativeToJavaCandidate(JNIEnv* env, - const IceCandidateInterface& candidate) { +jobject NativeToJavaIceCandidate(JNIEnv* env, + const IceCandidateInterface& candidate) { std::string sdp; RTC_CHECK(candidate.ToString(&sdp)) << "got so far: " << sdp; - return NativeToJavaCandidate(env, candidate.sdp_mid(), - candidate.sdp_mline_index(), sdp, - candidate.candidate().url()); + return CreateJavaIceCandidate(env, candidate.sdp_mid(), + candidate.sdp_mline_index(), sdp, + candidate.candidate().url()); } jobjectArray NativeToJavaCandidateArray( JNIEnv* jni, const std::vector& candidates) { - jobjectArray java_candidates = - Java_IceCandidate_createArray(jni, candidates.size()); - int i = 0; - for (const cricket::Candidate& candidate : candidates) { - jobject j_candidate = NativeToJavaCandidate(jni, candidate); - jni->SetObjectArrayElement(java_candidates, i++, j_candidate); - } - return java_candidates; + return NativeToJavaObjectArray(jni, candidates, + org_webrtc_IceCandidate_clazz(jni), + &NativeToJavaCandidate); } SessionDescriptionInterface* JavaToNativeSessionDescription(JNIEnv* jni, @@ -114,13 +108,13 @@ jobject NativeToJavaSessionDescription( const SessionDescriptionInterface* desc) { std::string sdp; RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp; - jstring j_description = JavaStringFromStdString(jni, sdp); + jstring j_description = NativeToJavaString(jni, sdp); jclass j_type_class = FindClass(jni, "org/webrtc/SessionDescription$Type"); jmethodID j_type_from_canonical = GetStaticMethodID( jni, j_type_class, "fromCanonicalForm", "(Ljava/lang/String;)Lorg/webrtc/SessionDescription$Type;"); - jstring j_type_string = JavaStringFromStdString(jni, desc->type()); + jstring j_type_string = NativeToJavaString(jni, desc->type()); jobject j_type = jni->CallStaticObjectMethod( j_type_class, j_type_from_canonical, j_type_string); CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; @@ -458,7 +452,7 @@ void JavaToNativeRTCConfiguration( jobject j_ice_check_min_interval = GetNullableObjectField(jni, j_rtc_config, j_ice_check_min_interval_id); rtc_config->ice_check_min_interval = - JavaIntegerToOptionalInt(jni, j_ice_check_min_interval); + JavaToNativeOptionalInt(jni, j_ice_check_min_interval); rtc_config->disable_ipv6_on_wifi = GetBooleanField(jni, j_rtc_config, j_disable_ipv6_on_wifi_id); rtc_config->max_ipv6_networks = @@ -505,7 +499,7 @@ void JavaToNativeRtpParameters(JNIEnv* jni, encoding.active = GetBooleanField(jni, j_encoding_parameters, active_id); jobject j_bitrate = GetNullableObjectField(jni, j_encoding_parameters, bitrate_id); - encoding.max_bitrate_bps = JavaIntegerToOptionalInt(jni, j_bitrate); + encoding.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_bitrate); jobject j_ssrc = GetNullableObjectField(jni, j_encoding_parameters, ssrc_id); if (!IsNull(jni, j_ssrc)) { @@ -535,10 +529,10 @@ void JavaToNativeRtpParameters(JNIEnv* jni, codec.kind = JavaToNativeMediaType(jni, GetObjectField(jni, j_codec, kind_id)); jobject j_clock_rate = GetNullableObjectField(jni, j_codec, clock_rate_id); - codec.clock_rate = JavaIntegerToOptionalInt(jni, j_clock_rate); + codec.clock_rate = JavaToNativeOptionalInt(jni, j_clock_rate); jobject j_num_channels = GetNullableObjectField(jni, j_codec, num_channels_id); - codec.num_channels = JavaIntegerToOptionalInt(jni, j_num_channels); + codec.num_channels = JavaToNativeOptionalInt(jni, j_num_channels); parameters->codecs.push_back(codec); } } @@ -574,9 +568,8 @@ jobject NativeToJavaRtpParameters(JNIEnv* jni, CHECK_EXCEPTION(jni) << "error during NewObject"; jni->SetBooleanField(j_encoding_parameters, active_id, encoding.active); CHECK_EXCEPTION(jni) << "error during SetBooleanField"; - jni->SetObjectField( - j_encoding_parameters, bitrate_id, - JavaIntegerFromOptionalInt(jni, encoding.max_bitrate_bps)); + jni->SetObjectField(j_encoding_parameters, bitrate_id, + NativeToJavaInteger(jni, encoding.max_bitrate_bps)); if (encoding.ssrc) { jobject j_ssrc_value = jni->NewObject(long_class, long_ctor, static_cast(*encoding.ssrc)); @@ -612,16 +605,15 @@ jobject NativeToJavaRtpParameters(JNIEnv* jni, CHECK_EXCEPTION(jni) << "error during NewObject"; jni->SetIntField(j_codec, payload_type_id, codec.payload_type); CHECK_EXCEPTION(jni) << "error during SetIntField"; - jni->SetObjectField(j_codec, name_id, - JavaStringFromStdString(jni, codec.name)); + jni->SetObjectField(j_codec, name_id, NativeToJavaString(jni, codec.name)); CHECK_EXCEPTION(jni) << "error during SetObjectField"; jni->SetObjectField(j_codec, kind_id, NativeToJavaMediaType(jni, codec.kind)); CHECK_EXCEPTION(jni) << "error during SetObjectField"; jni->SetObjectField(j_codec, clock_rate_id, - JavaIntegerFromOptionalInt(jni, codec.clock_rate)); + NativeToJavaInteger(jni, codec.clock_rate)); jni->SetObjectField(j_codec, num_channels_id, - JavaIntegerFromOptionalInt(jni, codec.num_channels)); + NativeToJavaInteger(jni, codec.num_channels)); jboolean added = jni->CallBooleanMethod(j_codecs, codecs_add, j_codec); CHECK_EXCEPTION(jni) << "error during CallBooleanMethod"; RTC_CHECK(added); diff --git a/sdk/android/src/jni/pc/java_native_conversion.h b/sdk/android/src/jni/pc/java_native_conversion.h index cb9f861991..faa4084aab 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.h +++ b/sdk/android/src/jni/pc/java_native_conversion.h @@ -38,8 +38,8 @@ cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate); jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate); -jobject NativeToJavaCandidate(JNIEnv* env, - const IceCandidateInterface& candidate); +jobject NativeToJavaIceCandidate(JNIEnv* env, + const IceCandidateInterface& candidate); jobjectArray NativeToJavaCandidateArray( JNIEnv* jni, diff --git a/sdk/android/src/jni/pc/mediastream_jni.cc b/sdk/android/src/jni/pc/mediastream_jni.cc index 010f355409..92f4c9d0c4 100644 --- a/sdk/android/src/jni/pc/mediastream_jni.cc +++ b/sdk/android/src/jni/pc/mediastream_jni.cc @@ -59,7 +59,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_p) { - return JavaStringFromStdString( + return NativeToJavaString( jni, reinterpret_cast(j_p)->label()); } diff --git a/sdk/android/src/jni/pc/mediastreamtrack_jni.cc b/sdk/android/src/jni/pc/mediastreamtrack_jni.cc index 0983bba84f..52c3794a3c 100644 --- a/sdk/android/src/jni/pc/mediastreamtrack_jni.cc +++ b/sdk/android/src/jni/pc/mediastreamtrack_jni.cc @@ -19,7 +19,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_p) { - return JavaStringFromStdString( + return NativeToJavaString( jni, reinterpret_cast(j_p)->id()); } @@ -28,7 +28,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_p) { - return JavaStringFromStdString( + return NativeToJavaString( jni, reinterpret_cast(j_p)->kind()); } diff --git a/sdk/android/src/jni/pc/peerconnection_jni.cc b/sdk/android/src/jni/pc/peerconnection_jni.cc index 075f38229b..c3f2d12d42 100644 --- a/sdk/android/src/jni/pc/peerconnection_jni.cc +++ b/sdk/android/src/jni/pc/peerconnection_jni.cc @@ -350,9 +350,9 @@ JNI_FUNCTION_DECLARATION(jboolean, jobject j_current, jobject j_max) { PeerConnectionInterface::BitrateParameters params; - params.min_bitrate_bps = JavaIntegerToOptionalInt(jni, j_min); - params.current_bitrate_bps = JavaIntegerToOptionalInt(jni, j_current); - params.max_bitrate_bps = JavaIntegerToOptionalInt(jni, j_max); + params.min_bitrate_bps = JavaToNativeOptionalInt(jni, j_min); + params.current_bitrate_bps = JavaToNativeOptionalInt(jni, j_current); + params.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_max); return ExtractNativePC(jni, j_pc)->SetBitrate(params).ok(); } diff --git a/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc b/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc index c42ed547c8..5882243e2e 100644 --- a/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionfactory_jni.cc @@ -104,7 +104,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jstring j_name) { - return JavaStringFromStdString( + return NativeToJavaString( jni, field_trial::FindFullName(JavaToStdString(jni, j_name))); } diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc index 3da15fae4e..4ad107eb91 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc @@ -16,6 +16,7 @@ #include "rtc_base/ptr_util.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaStream_jni.h" #include "sdk/android/src/jni/classreferenceholder.h" +#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/datachannel.h" #include "sdk/android/src/jni/pc/java_native_conversion.h" @@ -48,7 +49,7 @@ void PeerConnectionObserverJni::OnIceCandidate( const IceCandidateInterface* candidate) { JNIEnv* env = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(env); - jobject j_candidate = NativeToJavaCandidate(env, *candidate); + jobject j_candidate = NativeToJavaIceCandidate(env, *candidate); jmethodID m = GetMethodID(env, *j_observer_class_, "onIceCandidate", "(Lorg/webrtc/IceCandidate;)V"); diff --git a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc index 2e892e5333..f4d0b81a34 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc @@ -13,6 +13,8 @@ #include #include +#include "rtc_base/stringencode.h" +#include "sdk/android/generated_external_classes_jni/jni/BigInteger_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStatsCollectorCallback_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStatsReport_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStats_jni.h" @@ -21,11 +23,86 @@ namespace webrtc { namespace jni { +namespace { + +jobject NativeToJavaBigInteger(JNIEnv* env, uint64_t u) { + return JNI_BigInteger::Java_BigInteger_ConstructorJMBI_JLS( + env, NativeToJavaString(env, rtc::ToString(u))); +} + +jobjectArray NativeToJavaBigIntegerArray( + JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray( + env, container, java_math_BigInteger_clazz(env), &NativeToJavaBigInteger); +} + +jobject MemberToJava(JNIEnv* env, const RTCStatsMemberInterface& member) { + switch (member.type()) { + case RTCStatsMemberInterface::kBool: + return NativeToJavaBoolean(env, *member.cast_to>()); + + case RTCStatsMemberInterface::kInt32: + return NativeToJavaInteger(env, + *member.cast_to>()); + + case RTCStatsMemberInterface::kUint32: + return NativeToJavaLong(env, *member.cast_to>()); + + case RTCStatsMemberInterface::kInt64: + return NativeToJavaLong(env, *member.cast_to>()); + + case RTCStatsMemberInterface::kUint64: + return NativeToJavaBigInteger( + env, *member.cast_to>()); + + case RTCStatsMemberInterface::kDouble: + return NativeToJavaDouble(env, *member.cast_to>()); + + case RTCStatsMemberInterface::kString: + return NativeToJavaString(env, + *member.cast_to>()); + + case RTCStatsMemberInterface::kSequenceBool: + return NativeToJavaBooleanArray( + env, *member.cast_to>>()); + + case RTCStatsMemberInterface::kSequenceInt32: + return NativeToJavaIntegerArray( + env, *member.cast_to>>()); + + case RTCStatsMemberInterface::kSequenceUint32: { + const std::vector& v = + *member.cast_to>>(); + return NativeToJavaLongArray(env, + std::vector(v.begin(), v.end())); + } + case RTCStatsMemberInterface::kSequenceInt64: + return NativeToJavaLongArray( + env, *member.cast_to>>()); + + case RTCStatsMemberInterface::kSequenceUint64: + return NativeToJavaBigIntegerArray( + env, *member.cast_to>>()); + + case RTCStatsMemberInterface::kSequenceDouble: + return NativeToJavaDoubleArray( + env, *member.cast_to>>()); + + case RTCStatsMemberInterface::kSequenceString: + return NativeToJavaStringArray( + env, *member.cast_to>>()); + } + RTC_NOTREACHED(); + return nullptr; +} + +} // namespace + RTCStatsCollectorCallbackWrapper::RTCStatsCollectorCallbackWrapper( JNIEnv* jni, jobject j_callback) : j_callback_global_(jni, j_callback), - j_callback_class_(jni, GetObjectClass(jni, j_callback)), j_linked_hash_map_class_(FindClass(jni, "java/util/LinkedHashMap")), j_linked_hash_map_ctor_( GetMethodID(jni, j_linked_hash_map_class_, "", "()V")), @@ -33,20 +110,7 @@ RTCStatsCollectorCallbackWrapper::RTCStatsCollectorCallbackWrapper( jni, j_linked_hash_map_class_, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")), - j_boolean_class_(FindClass(jni, "java/lang/Boolean")), - j_boolean_ctor_(GetMethodID(jni, j_boolean_class_, "", "(Z)V")), - j_integer_class_(jni->FindClass("java/lang/Integer")), - j_long_class_(FindClass(jni, "java/lang/Long")), - j_long_ctor_(GetMethodID(jni, j_long_class_, "", "(J)V")), - j_big_integer_class_(FindClass(jni, "java/math/BigInteger")), - j_big_integer_ctor_(GetMethodID(jni, - j_big_integer_class_, - "", - "(Ljava/lang/String;)V")), - j_double_class_(FindClass(jni, "java/lang/Double")), - j_double_ctor_(GetMethodID(jni, j_double_class_, "", "(D)V")), - j_string_class_(FindClass(jni, "java/lang/String")) {} + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")) {} void RTCStatsCollectorCallbackWrapper::OnStatsDelivered( const rtc::scoped_refptr& report) { @@ -67,7 +131,7 @@ jobject RTCStatsCollectorCallbackWrapper::ReportToJava( // Create a local reference frame for each RTCStats, since there is a // maximum number of references that can be created in one frame. ScopedLocalRefFrame local_ref_frame(jni); - jstring j_id = JavaStringFromStdString(jni, stats.id()); + jstring j_id = NativeToJavaString(jni, stats.id()); jobject j_stats = StatsToJava(jni, stats); jni->CallObjectMethod(j_stats_map, j_linked_hash_map_put_, j_id, j_stats); CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; @@ -79,8 +143,8 @@ jobject RTCStatsCollectorCallbackWrapper::ReportToJava( jobject RTCStatsCollectorCallbackWrapper::StatsToJava(JNIEnv* jni, const RTCStats& stats) { - jstring j_type = JavaStringFromStdString(jni, stats.type()); - jstring j_id = JavaStringFromStdString(jni, stats.id()); + jstring j_type = NativeToJavaString(jni, stats.type()); + jstring j_id = NativeToJavaString(jni, stats.id()); jobject j_members = jni->NewObject(j_linked_hash_map_class_, j_linked_hash_map_ctor_); for (const RTCStatsMemberInterface* member : stats.Members()) { @@ -89,8 +153,8 @@ jobject RTCStatsCollectorCallbackWrapper::StatsToJava(JNIEnv* jni, } // Create a local reference frame for each member as well. ScopedLocalRefFrame local_ref_frame(jni); - jstring j_name = JavaStringFromStdString(jni, member->name()); - jobject j_member = MemberToJava(jni, member); + jstring j_name = NativeToJavaString(jni, member->name()); + jobject j_member = MemberToJava(jni, *member); jni->CallObjectMethod(j_members, j_linked_hash_map_put_, j_name, j_member); CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; } @@ -100,151 +164,5 @@ jobject RTCStatsCollectorCallbackWrapper::StatsToJava(JNIEnv* jni, return j_stats; } -jobject RTCStatsCollectorCallbackWrapper::MemberToJava( - JNIEnv* jni, - const RTCStatsMemberInterface* member) { - switch (member->type()) { - case RTCStatsMemberInterface::kBool: { - jobject value = jni->NewObject(j_boolean_class_, j_boolean_ctor_, - *member->cast_to>()); - CHECK_EXCEPTION(jni) << "error during NewObject"; - return value; - } - case RTCStatsMemberInterface::kInt32: { - return JavaIntegerFromInt(jni, - *member->cast_to>()); - } - case RTCStatsMemberInterface::kUint32: { - jobject value = - jni->NewObject(j_long_class_, j_long_ctor_, - (jlong)*member->cast_to>()); - CHECK_EXCEPTION(jni) << "error during NewObject"; - return value; - } - case RTCStatsMemberInterface::kInt64: { - jobject value = - jni->NewObject(j_long_class_, j_long_ctor_, - *member->cast_to>()); - CHECK_EXCEPTION(jni) << "error during NewObject"; - return value; - } - case 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 RTCStatsMemberInterface::kDouble: { - jobject value = - jni->NewObject(j_double_class_, j_double_ctor_, - *member->cast_to>()); - CHECK_EXCEPTION(jni) << "error during NewObject"; - return value; - } - case RTCStatsMemberInterface::kString: { - return JavaStringFromStdString( - jni, *member->cast_to>()); - } - case RTCStatsMemberInterface::kSequenceBool: { - const std::vector& values = - *member->cast_to>>(); - 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 RTCStatsMemberInterface::kSequenceInt32: { - const std::vector& values = - *member->cast_to>>(); - 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) { - jni->SetObjectArrayElement(j_values, i, - JavaIntegerFromInt(jni, values[i])); - CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement"; - } - return j_values; - } - case RTCStatsMemberInterface::kSequenceUint32: { - const std::vector& values = - *member->cast_to>>(); - 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 RTCStatsMemberInterface::kSequenceInt64: { - const std::vector& values = - *member->cast_to>>(); - 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 RTCStatsMemberInterface::kSequenceUint64: { - const std::vector& values = - *member->cast_to>>(); - 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 RTCStatsMemberInterface::kSequenceDouble: { - const std::vector& values = - *member->cast_to>>(); - 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 RTCStatsMemberInterface::kSequenceString: { - const std::vector& values = - *member->cast_to>>(); - 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; -} - } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h index 8914a5d56d..d9cc6923d1 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h @@ -34,23 +34,11 @@ class RTCStatsCollectorCallbackWrapper : public RTCStatsCollectorCallback { jobject ReportToJava(JNIEnv* jni, const rtc::scoped_refptr& report); jobject StatsToJava(JNIEnv* jni, const RTCStats& stats); - jobject MemberToJava(JNIEnv* jni, const RTCStatsMemberInterface* member); const ScopedGlobalRef j_callback_global_; - const ScopedGlobalRef j_callback_class_; const jclass j_linked_hash_map_class_; const jmethodID j_linked_hash_map_ctor_; const jmethodID j_linked_hash_map_put_; - const jclass j_boolean_class_; - const jmethodID j_boolean_ctor_; - const jclass j_integer_class_; - const jclass j_long_class_; - const jmethodID j_long_ctor_; - const jclass j_big_integer_class_; - const jmethodID j_big_integer_ctor_; - const jclass j_double_class_; - const jmethodID j_double_ctor_; - const jclass j_string_class_; }; } // namespace jni diff --git a/sdk/android/src/jni/pc/rtpreceiver_jni.cc b/sdk/android/src/jni/pc/rtpreceiver_jni.cc index 521ea60007..eb60cc0c0f 100644 --- a/sdk/android/src/jni/pc/rtpreceiver_jni.cc +++ b/sdk/android/src/jni/pc/rtpreceiver_jni.cc @@ -59,7 +59,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer) { - return JavaStringFromStdString( + return NativeToJavaString( jni, reinterpret_cast(j_rtp_receiver_pointer)->id()); } diff --git a/sdk/android/src/jni/pc/rtpsender_jni.cc b/sdk/android/src/jni/pc/rtpsender_jni.cc index e307480e49..a30bc6c87e 100644 --- a/sdk/android/src/jni/pc/rtpsender_jni.cc +++ b/sdk/android/src/jni/pc/rtpsender_jni.cc @@ -78,7 +78,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_rtp_sender_pointer) { - return JavaStringFromStdString( + return NativeToJavaString( jni, reinterpret_cast(j_rtp_sender_pointer)->id()); } diff --git a/sdk/android/src/jni/pc/sdpobserver_jni.h b/sdk/android/src/jni/pc/sdpobserver_jni.h index 9b8db6330a..5ed3b59acf 100644 --- a/sdk/android/src/jni/pc/sdpobserver_jni.h +++ b/sdk/android/src/jni/pc/sdpobserver_jni.h @@ -64,7 +64,7 @@ class SdpObserverJni : public T { void DoOnFailure(const std::string& op, const std::string& error) { jmethodID m = GetMethodID(jni(), *j_observer_class_, "on" + op + "Failure", "(Ljava/lang/String;)V"); - jstring j_error_string = JavaStringFromStdString(jni(), error); + jstring j_error_string = NativeToJavaString(jni(), error); jni()->CallVoidMethod(*j_observer_global_, m, j_error_string); CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; } diff --git a/sdk/android/src/jni/pc/statsobserver_jni.cc b/sdk/android/src/jni/pc/statsobserver_jni.cc index 1c7f873690..32d2e8cda6 100644 --- a/sdk/android/src/jni/pc/statsobserver_jni.cc +++ b/sdk/android/src/jni/pc/statsobserver_jni.cc @@ -10,75 +10,67 @@ #include "sdk/android/src/jni/pc/statsobserver_jni.h" -#include "sdk/android/src/jni/classreferenceholder.h" +#include "sdk/android/generated_peerconnection_jni/jni/StatsObserver_jni.h" +#include "sdk/android/generated_peerconnection_jni/jni/StatsReport_jni.h" +#include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { namespace jni { -// Convenience, used since callbacks occur on the signaling thread, which may -// be a non-Java thread. -static JNIEnv* jni() { - return AttachCurrentThreadIfNeeded(); +namespace { + +jobject NativeToJavaStatsReportValue( + JNIEnv* env, + const rtc::scoped_refptr& value_ptr) { + // Should we use the '.name' enum value here instead of converting the + // name to a string? + jstring j_name = NativeToJavaString(env, value_ptr->display_name()); + jstring j_value = NativeToJavaString(env, value_ptr->ToString()); + jobject ret = Java_Value_Constructor(env, j_name, j_value); + env->DeleteLocalRef(j_name); + env->DeleteLocalRef(j_value); + return ret; } +jobjectArray NativeToJavaStatsReportValueArray( + JNIEnv* env, + const StatsReport::Values& value_map) { + // Ignore the keys and make an array out of the values. + std::vector values; + for (const auto& it : value_map) + values.push_back(it.second); + return NativeToJavaObjectArray(env, values, + org_webrtc_StatsReport_00024Value_clazz(env), + &NativeToJavaStatsReportValue); +} + +jobject NativeToJavaStatsReport(JNIEnv* env, const StatsReport& report) { + jstring j_id = NativeToJavaString(env, report.id()->ToString()); + jstring j_type = NativeToJavaString(env, report.TypeToString()); + jobjectArray j_values = + NativeToJavaStatsReportValueArray(env, report.values()); + jobject ret = Java_StatsReport_Constructor(env, j_id, j_type, + report.timestamp(), j_values); + env->DeleteLocalRef(j_values); + env->DeleteLocalRef(j_type); + env->DeleteLocalRef(j_id); + return ret; +} + +} // namespace + StatsObserverJni::StatsObserverJni(JNIEnv* jni, jobject j_observer) - : j_observer_global_(jni, j_observer), - j_observer_class_(jni, GetObjectClass(jni, j_observer)), - j_stats_report_class_(jni, FindClass(jni, "org/webrtc/StatsReport")), - j_stats_report_ctor_(GetMethodID(jni, - *j_stats_report_class_, - "", - "(Ljava/lang/String;Ljava/lang/String;D" - "[Lorg/webrtc/StatsReport$Value;)V")), - j_value_class_(jni, FindClass(jni, "org/webrtc/StatsReport$Value")), - j_value_ctor_(GetMethodID(jni, - *j_value_class_, - "", - "(Ljava/lang/String;Ljava/lang/String;)V")) {} + : j_observer_global_(jni, j_observer) {} void StatsObserverJni::OnComplete(const StatsReports& reports) { - ScopedLocalRefFrame local_ref_frame(jni()); - jobjectArray j_reports = ReportsToJava(jni(), reports); - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onComplete", - "([Lorg/webrtc/StatsReport;)V"); - jni()->CallVoidMethod(*j_observer_global_, m, j_reports); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; -} - -jobjectArray StatsObserverJni::ReportsToJava(JNIEnv* jni, - const StatsReports& reports) { - jobjectArray reports_array = - jni->NewObjectArray(reports.size(), *j_stats_report_class_, NULL); - int i = 0; - for (const auto* report : reports) { - ScopedLocalRefFrame local_ref_frame(jni); - jstring j_id = JavaStringFromStdString(jni, report->id()->ToString()); - jstring j_type = JavaStringFromStdString(jni, report->TypeToString()); - jobjectArray j_values = ValuesToJava(jni, report->values()); - jobject j_report = - jni->NewObject(*j_stats_report_class_, j_stats_report_ctor_, j_id, - j_type, report->timestamp(), j_values); - jni->SetObjectArrayElement(reports_array, i++, j_report); - } - return reports_array; -} - -jobjectArray StatsObserverJni::ValuesToJava(JNIEnv* jni, - const StatsReport::Values& values) { - jobjectArray j_values = - jni->NewObjectArray(values.size(), *j_value_class_, NULL); - int i = 0; - for (const auto& it : values) { - ScopedLocalRefFrame local_ref_frame(jni); - // Should we use the '.name' enum value here instead of converting the - // name to a string? - jstring j_name = JavaStringFromStdString(jni, it.second->display_name()); - jstring j_value = JavaStringFromStdString(jni, it.second->ToString()); - jobject j_element_value = - jni->NewObject(*j_value_class_, j_value_ctor_, j_name, j_value); - jni->SetObjectArrayElement(j_values, i++, j_element_value); - } - return j_values; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + jobjectArray j_reports = + NativeToJavaObjectArray(env, reports, org_webrtc_StatsReport_clazz(env), + [](JNIEnv* env, const StatsReport* report) { + return NativeToJavaStatsReport(env, *report); + }); + Java_StatsObserver_onComplete(env, *j_observer_global_, j_reports); + env->DeleteLocalRef(j_reports); } } // namespace jni diff --git a/sdk/android/src/jni/pc/statsobserver_jni.h b/sdk/android/src/jni/pc/statsobserver_jni.h index d1e2224567..ec5d4fdd70 100644 --- a/sdk/android/src/jni/pc/statsobserver_jni.h +++ b/sdk/android/src/jni/pc/statsobserver_jni.h @@ -26,16 +26,7 @@ class StatsObserverJni : public StatsObserver { void OnComplete(const StatsReports& reports) override; private: - jobjectArray ReportsToJava(JNIEnv* jni, const StatsReports& reports); - - jobjectArray ValuesToJava(JNIEnv* jni, const StatsReport::Values& values); - const ScopedGlobalRef j_observer_global_; - const ScopedGlobalRef j_observer_class_; - const ScopedGlobalRef j_stats_report_class_; - const jmethodID j_stats_report_ctor_; - const ScopedGlobalRef j_value_class_; - const jmethodID j_value_ctor_; }; } // namespace jni diff --git a/sdk/android/src/jni/videocodecinfo.cc b/sdk/android/src/jni/videocodecinfo.cc index 2566673dfe..2412649199 100644 --- a/sdk/android/src/jni/videocodecinfo.cc +++ b/sdk/android/src/jni/videocodecinfo.cc @@ -46,11 +46,11 @@ jobject SdpVideoFormatToVideoCodecInfo(JNIEnv* jni, jobject j_params = jni->NewObject(hash_map_class, hash_map_constructor); for (auto const& param : format.parameters) { jni->CallObjectMethod(j_params, put_method, - JavaStringFromStdString(jni, param.first), - JavaStringFromStdString(jni, param.second)); + NativeToJavaString(jni, param.first), + NativeToJavaString(jni, param.second)); } return jni->NewObject(video_codec_info_class, video_codec_info_constructor, - JavaStringFromStdString(jni, format.name), j_params); + NativeToJavaString(jni, format.name), j_params); } } // namespace jni diff --git a/sdk/android/src/jni/videodecoderfactorywrapper.cc b/sdk/android/src/jni/videodecoderfactorywrapper.cc index cda9c4b483..e687289ad3 100644 --- a/sdk/android/src/jni/videodecoderfactorywrapper.cc +++ b/sdk/android/src/jni/videodecoderfactorywrapper.cc @@ -32,7 +32,7 @@ std::unique_ptr VideoDecoderFactoryWrapper::CreateVideoDecoder( const SdpVideoFormat& format) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(jni); - jstring name = JavaStringFromStdString(jni, format.name); + jstring name = NativeToJavaString(jni, format.name); jobject decoder = jni->CallObjectMethod(*decoder_factory_, create_decoder_method_, name); return decoder != nullptr ? JavaToNativeVideoDecoder(jni, decoder) : nullptr; diff --git a/sdk/android/src/jni/videodecoderwrapper.cc b/sdk/android/src/jni/videodecoderwrapper.cc index 6b29c0eefe..30377db0a0 100644 --- a/sdk/android/src/jni/videodecoderwrapper.cc +++ b/sdk/android/src/jni/videodecoderwrapper.cc @@ -160,10 +160,10 @@ void VideoDecoderWrapper::OnDecodedFrame(JNIEnv* env, frame.set_ntp_time_ms(frame_extra_info.timestamp_ntp); rtc::Optional decoding_time_ms = - JavaIntegerToOptionalInt(env, j_decode_time_ms); + JavaToNativeOptionalInt(env, j_decode_time_ms); rtc::Optional decoder_qp = - cast_optional(JavaIntegerToOptionalInt(env, j_qp)); + cast_optional(JavaToNativeOptionalInt(env, j_qp)); // If the decoder provides QP values itself, no need to parse the bitstream. // Enable QP parsing if decoder does not provide QP values itself. qp_parsing_enabled_ = !decoder_qp.has_value(); diff --git a/sdk/android/src/jni/videoencoderwrapper.cc b/sdk/android/src/jni/videoencoderwrapper.cc index 19c00ec371..13b0e37c16 100644 --- a/sdk/android/src/jni/videoencoderwrapper.cc +++ b/sdk/android/src/jni/videoencoderwrapper.cc @@ -121,12 +121,7 @@ int32_t VideoEncoderWrapper::Encode( ScopedLocalRefFrame local_ref_frame(jni); // Construct encode info. - jobjectArray j_frame_types = - jni->NewObjectArray(frame_types->size(), *frame_type_class_, nullptr); - for (size_t i = 0; i < frame_types->size(); ++i) { - jobject j_frame_type = NativeToJavaFrameType(jni, (*frame_types)[i]); - jni->SetObjectArrayElement(j_frame_types, i, j_frame_type); - } + jobjectArray j_frame_types = NativeToJavaFrameTypeArray(jni, *frame_types); jobject encode_info = Java_EncodeInfo_Constructor(jni, j_frame_types); FrameExtraInfo info; @@ -169,10 +164,10 @@ VideoEncoderWrapper::ScalingSettings VideoEncoderWrapper::GetScalingSettings() bool isOn = Java_VideoEncoderWrapper_getScalingSettingsOn(jni, j_scaling_settings); - rtc::Optional low = JavaIntegerToOptionalInt( + rtc::Optional low = JavaToNativeOptionalInt( jni, Java_VideoEncoderWrapper_getScalingSettingsLow(jni, j_scaling_settings)); - rtc::Optional high = JavaIntegerToOptionalInt( + rtc::Optional high = JavaToNativeOptionalInt( jni, Java_VideoEncoderWrapper_getScalingSettingsHigh(jni, j_scaling_settings)); @@ -200,7 +195,7 @@ void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni, std::vector buffer_copy(buffer_size); memcpy(buffer_copy.data(), buffer, buffer_size); - const int qp = JavaIntegerToOptionalInt(jni, j_qp).value_or(-1); + const int qp = JavaToNativeOptionalInt(jni, j_qp).value_or(-1); encoder_queue_->PostTask( [