From 43d069a2cdb90ec8c887cf8aa68b42b7cf7ea49d Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Wed, 29 Nov 2017 10:08:57 +0000 Subject: [PATCH] Revert "Android: Generate JNI code for stats" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit aede67a199ae0552074bfec4bb03cc9a6a5fba0f. Reason for revert: Causes error: JNI ERROR (app bug): local reference table overflow (max=512)' Original change's description: > Android: Generate JNI code for stats > > This CL also unifies the functions for converting from C++ to Java, and > generates the boiler plate for converting C++ vectors to Java arrays. > > Bug: webrtc:8278 > Change-Id: I262e9162beae8a64ba0e8b6a27e1081207b03961 > Reviewed-on: https://webrtc-review.googlesource.com/26020 > Commit-Queue: Magnus Jedvert > Reviewed-by: Sami Kalliomäki > Cr-Commit-Position: refs/heads/master@{#20918} TBR=magjed@webrtc.org,sakal@webrtc.org Change-Id: Ieb26ed8577bd489a4dd4f7542d16a7d0e11f409f No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:8278 Reviewed-on: https://webrtc-review.googlesource.com/26900 Reviewed-by: Magnus Jedvert Commit-Queue: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#20926} --- sdk/android/BUILD.gn | 12 +- sdk/android/api/org/webrtc/IceCandidate.java | 5 + sdk/android/api/org/webrtc/StatsObserver.java | 2 +- sdk/android/api/org/webrtc/StatsReport.java | 2 - sdk/android/src/jni/classreferenceholder.cc | 4 + sdk/android/src/jni/encodedimage.cc | 12 +- sdk/android/src/jni/encodedimage.h | 4 +- sdk/android/src/jni/jni_helpers.cc | 72 +---- sdk/android/src/jni/jni_helpers.h | 48 +--- sdk/android/src/jni/pc/datachannel.cc | 2 +- sdk/android/src/jni/pc/dtmfsender_jni.cc | 2 +- .../src/jni/pc/java_native_conversion.cc | 66 +++-- .../src/jni/pc/java_native_conversion.h | 4 +- sdk/android/src/jni/pc/mediastream_jni.cc | 2 +- .../src/jni/pc/mediastreamtrack_jni.cc | 4 +- sdk/android/src/jni/pc/peerconnection_jni.cc | 6 +- .../src/jni/pc/peerconnectionfactory_jni.cc | 2 +- .../src/jni/pc/peerconnectionobserver_jni.cc | 3 +- .../pc/rtcstatscollectorcallbackwrapper.cc | 250 ++++++++++++------ .../jni/pc/rtcstatscollectorcallbackwrapper.h | 12 + sdk/android/src/jni/pc/rtpreceiver_jni.cc | 2 +- sdk/android/src/jni/pc/rtpsender_jni.cc | 2 +- sdk/android/src/jni/pc/sdpobserver_jni.h | 2 +- sdk/android/src/jni/pc/statsobserver_jni.cc | 105 ++++---- sdk/android/src/jni/pc/statsobserver_jni.h | 9 + sdk/android/src/jni/videocodecinfo.cc | 6 +- .../src/jni/videodecoderfactorywrapper.cc | 2 +- sdk/android/src/jni/videodecoderwrapper.cc | 4 +- sdk/android/src/jni/videoencoderwrapper.cc | 13 +- 29 files changed, 347 insertions(+), 312 deletions(-) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index c7427da178..c7738cc5e2 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -42,14 +42,7 @@ generate_jni("generated_base_jni") { } generate_jar_jni("generated_external_classes_jni") { - 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", - ] + classes = [ "java/lang/Integer.class" ] jni_package = "" jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" } @@ -301,8 +294,6 @@ 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" @@ -366,7 +357,6 @@ 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 eebc9d9fa6..51865e9f16 100644 --- a/sdk/android/api/org/webrtc/IceCandidate.java +++ b/sdk/android/api/org/webrtc/IceCandidate.java @@ -49,4 +49,9 @@ 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 b9984c18db..b1ad0dea21 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.*/ - @CalledByNative public void onComplete(StatsReport[] reports); + public void onComplete(StatsReport[] reports); } diff --git a/sdk/android/api/org/webrtc/StatsReport.java b/sdk/android/api/org/webrtc/StatsReport.java index b8f1cf87fe..b5396fc860 100644 --- a/sdk/android/api/org/webrtc/StatsReport.java +++ b/sdk/android/api/org/webrtc/StatsReport.java @@ -17,7 +17,6 @@ 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; @@ -37,7 +36,6 @@ 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 b1f8fdaaf6..a175a0fbb9 100644 --- a/sdk/android/src/jni/classreferenceholder.cc +++ b/sdk/android/src/jni/classreferenceholder.cc @@ -51,7 +51,11 @@ 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 81c5caa761..966ef93d39 100644 --- a/sdk/android/src/jni/encodedimage.cc +++ b/sdk/android/src/jni/encodedimage.cc @@ -13,7 +13,6 @@ #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 { @@ -25,21 +24,12 @@ 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 : NativeToJavaInteger(jni, image.qp_); + jobject qp = (image.qp_ == -1) ? nullptr : JavaIntegerFromInt(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 563b0d0095..a84b91e3c7 100644 --- a/sdk/android/src/jni/encodedimage.h +++ b/sdk/android/src/jni/encodedimage.h @@ -13,6 +13,7 @@ #include +#include "api/video/video_rotation.h" #include "common_types.h" // NOLINT(build/include) namespace webrtc { @@ -23,9 +24,6 @@ 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 694ebead2c..fa8adc307a 100644 --- a/sdk/android/src/jni/jni_helpers.cc +++ b/sdk/android/src/jni/jni_helpers.cc @@ -15,10 +15,7 @@ #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" @@ -236,6 +233,13 @@ 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| @@ -271,39 +275,21 @@ std::vector JavaToStdVectorStrings(JNIEnv* jni, jobject list) { return converted_list; } -rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer) { +rtc::Optional JavaIntegerToOptionalInt(JNIEnv* jni, jobject integer) { if (IsNull(jni, integer)) return rtc::nullopt; return JNI_Integer::Java_Integer_intValue(jni, integer); } -jobject NativeToJavaBoolean(JNIEnv* env, bool b) { - return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b); +jobject JavaIntegerFromOptionalInt(JNIEnv* jni, + const rtc::Optional& optional_int) { + return optional_int ? JavaIntegerFromInt(jni, *optional_int) : nullptr; } -jobject NativeToJavaInteger(JNIEnv* jni, int32_t i) { +jobject JavaIntegerFromInt(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) { @@ -467,39 +453,5 @@ 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 bfef3a8802..e18edc2d40 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -98,6 +98,9 @@ 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); @@ -105,16 +108,12 @@ 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 JavaToNativeOptionalInt(JNIEnv* jni, jobject integer); +rtc::Optional JavaIntegerToOptionalInt(JNIEnv* jni, jobject integer); -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); +jobject JavaIntegerFromOptionalInt(JNIEnv* jni, + const rtc::Optional& optional_int); + +jobject JavaIntegerFromInt(JNIEnv* jni, int32_t i); // Return the (singleton) Java Enum object corresponding to |index|; jobject JavaEnumFromIndex(JNIEnv* jni, jclass state_class, @@ -229,37 +228,6 @@ 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 c4be431827..758e4b90e7 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 NativeToJavaString(jni, ExtractNativeDC(jni, j_dc)->label()); + return JavaStringFromStdString(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 c8d5493d7e..a21314a112 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 NativeToJavaString( + return JavaStringFromStdString( 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 3f0e2e1e1b..ee4640b106 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.cc +++ b/sdk/android/src/jni/pc/java_native_conversion.cc @@ -22,14 +22,15 @@ namespace jni { namespace { -jobject CreateJavaIceCandidate(JNIEnv* env, - const std::string& sdp_mid, - int sdp_mline_index, - const std::string& sdp, - const std::string server_url) { +jobject NativeToJavaCandidate(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, NativeToJavaString(env, sdp_mid), sdp_mline_index, - NativeToJavaString(env, sdp), NativeToJavaString(env, server_url)); + env, JavaStringFromStdString(env, sdp_mid), sdp_mline_index, + JavaStringFromStdString(env, sdp), + JavaStringFromStdString(env, server_url)); } } // namespace @@ -60,26 +61,31 @@ 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 CreateJavaIceCandidate(env, candidate.transport_name(), - -1 /* sdp_mline_index */, sdp, - "" /* server_url */); + return NativeToJavaCandidate(env, candidate.transport_name(), + -1 /* sdp_mline_index */, sdp, + "" /* server_url */); } -jobject NativeToJavaIceCandidate(JNIEnv* env, - const IceCandidateInterface& candidate) { +jobject NativeToJavaCandidate(JNIEnv* env, + const IceCandidateInterface& candidate) { std::string sdp; RTC_CHECK(candidate.ToString(&sdp)) << "got so far: " << sdp; - return CreateJavaIceCandidate(env, candidate.sdp_mid(), - candidate.sdp_mline_index(), sdp, - candidate.candidate().url()); + return NativeToJavaCandidate(env, candidate.sdp_mid(), + candidate.sdp_mline_index(), sdp, + candidate.candidate().url()); } jobjectArray NativeToJavaCandidateArray( JNIEnv* jni, const std::vector& candidates) { - return NativeToJavaObjectArray(jni, candidates, - org_webrtc_IceCandidate_clazz(jni), - &NativeToJavaCandidate); + 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; } SessionDescriptionInterface* JavaToNativeSessionDescription(JNIEnv* jni, @@ -108,13 +114,13 @@ jobject NativeToJavaSessionDescription( const SessionDescriptionInterface* desc) { std::string sdp; RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp; - jstring j_description = NativeToJavaString(jni, sdp); + jstring j_description = JavaStringFromStdString(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 = NativeToJavaString(jni, desc->type()); + jstring j_type_string = JavaStringFromStdString(jni, desc->type()); jobject j_type = jni->CallStaticObjectMethod( j_type_class, j_type_from_canonical, j_type_string); CHECK_EXCEPTION(jni) << "error during CallObjectMethod"; @@ -452,7 +458,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 = - JavaToNativeOptionalInt(jni, j_ice_check_min_interval); + JavaIntegerToOptionalInt(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 = @@ -499,7 +505,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 = JavaToNativeOptionalInt(jni, j_bitrate); + encoding.max_bitrate_bps = JavaIntegerToOptionalInt(jni, j_bitrate); jobject j_ssrc = GetNullableObjectField(jni, j_encoding_parameters, ssrc_id); if (!IsNull(jni, j_ssrc)) { @@ -529,10 +535,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 = JavaToNativeOptionalInt(jni, j_clock_rate); + codec.clock_rate = JavaIntegerToOptionalInt(jni, j_clock_rate); jobject j_num_channels = GetNullableObjectField(jni, j_codec, num_channels_id); - codec.num_channels = JavaToNativeOptionalInt(jni, j_num_channels); + codec.num_channels = JavaIntegerToOptionalInt(jni, j_num_channels); parameters->codecs.push_back(codec); } } @@ -568,8 +574,9 @@ 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, - NativeToJavaInteger(jni, encoding.max_bitrate_bps)); + jni->SetObjectField( + j_encoding_parameters, bitrate_id, + JavaIntegerFromOptionalInt(jni, encoding.max_bitrate_bps)); if (encoding.ssrc) { jobject j_ssrc_value = jni->NewObject(long_class, long_ctor, static_cast(*encoding.ssrc)); @@ -605,15 +612,16 @@ 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, NativeToJavaString(jni, codec.name)); + jni->SetObjectField(j_codec, name_id, + JavaStringFromStdString(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, - NativeToJavaInteger(jni, codec.clock_rate)); + JavaIntegerFromOptionalInt(jni, codec.clock_rate)); jni->SetObjectField(j_codec, num_channels_id, - NativeToJavaInteger(jni, codec.num_channels)); + JavaIntegerFromOptionalInt(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 faa4084aab..cb9f861991 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 NativeToJavaIceCandidate(JNIEnv* env, - const IceCandidateInterface& candidate); +jobject NativeToJavaCandidate(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 92f4c9d0c4..010f355409 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 NativeToJavaString( + return JavaStringFromStdString( 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 52c3794a3c..0983bba84f 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 NativeToJavaString( + return JavaStringFromStdString( jni, reinterpret_cast(j_p)->id()); } @@ -28,7 +28,7 @@ JNI_FUNCTION_DECLARATION(jstring, JNIEnv* jni, jclass, jlong j_p) { - return NativeToJavaString( + return JavaStringFromStdString( 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 c3f2d12d42..075f38229b 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 = JavaToNativeOptionalInt(jni, j_min); - params.current_bitrate_bps = JavaToNativeOptionalInt(jni, j_current); - params.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_max); + params.min_bitrate_bps = JavaIntegerToOptionalInt(jni, j_min); + params.current_bitrate_bps = JavaIntegerToOptionalInt(jni, j_current); + params.max_bitrate_bps = JavaIntegerToOptionalInt(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 5882243e2e..c42ed547c8 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 NativeToJavaString( + return JavaStringFromStdString( 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 4ad107eb91..3da15fae4e 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc @@ -16,7 +16,6 @@ #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" @@ -49,7 +48,7 @@ void PeerConnectionObserverJni::OnIceCandidate( const IceCandidateInterface* candidate) { JNIEnv* env = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(env); - jobject j_candidate = NativeToJavaIceCandidate(env, *candidate); + jobject j_candidate = NativeToJavaCandidate(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 f4d0b81a34..2e892e5333 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc @@ -13,8 +13,6 @@ #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" @@ -23,86 +21,11 @@ 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")), @@ -110,7 +33,20 @@ RTCStatsCollectorCallbackWrapper::RTCStatsCollectorCallbackWrapper( jni, j_linked_hash_map_class_, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")) {} + "(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")) {} void RTCStatsCollectorCallbackWrapper::OnStatsDelivered( const rtc::scoped_refptr& report) { @@ -131,7 +67,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 = NativeToJavaString(jni, stats.id()); + jstring j_id = JavaStringFromStdString(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"; @@ -143,8 +79,8 @@ jobject RTCStatsCollectorCallbackWrapper::ReportToJava( jobject RTCStatsCollectorCallbackWrapper::StatsToJava(JNIEnv* jni, const RTCStats& stats) { - jstring j_type = NativeToJavaString(jni, stats.type()); - jstring j_id = NativeToJavaString(jni, stats.id()); + jstring j_type = JavaStringFromStdString(jni, stats.type()); + jstring j_id = JavaStringFromStdString(jni, stats.id()); jobject j_members = jni->NewObject(j_linked_hash_map_class_, j_linked_hash_map_ctor_); for (const RTCStatsMemberInterface* member : stats.Members()) { @@ -153,8 +89,8 @@ jobject RTCStatsCollectorCallbackWrapper::StatsToJava(JNIEnv* jni, } // Create a local reference frame for each member as well. ScopedLocalRefFrame local_ref_frame(jni); - jstring j_name = NativeToJavaString(jni, member->name()); - jobject j_member = MemberToJava(jni, *member); + jstring j_name = JavaStringFromStdString(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"; } @@ -164,5 +100,151 @@ 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 d9cc6923d1..8914a5d56d 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h @@ -34,11 +34,23 @@ 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 eb60cc0c0f..521ea60007 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 NativeToJavaString( + return JavaStringFromStdString( 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 a30bc6c87e..e307480e49 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 NativeToJavaString( + return JavaStringFromStdString( 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 5ed3b59acf..9b8db6330a 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 = NativeToJavaString(jni(), error); + jstring j_error_string = JavaStringFromStdString(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 f91a491bc1..1c7f873690 100644 --- a/sdk/android/src/jni/pc/statsobserver_jni.cc +++ b/sdk/android/src/jni/pc/statsobserver_jni.cc @@ -10,60 +10,75 @@ #include "sdk/android/src/jni/pc/statsobserver_jni.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" +#include "sdk/android/src/jni/classreferenceholder.h" namespace webrtc { namespace jni { -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()); - return Java_Value_Constructor(env, j_name, j_value); +// Convenience, used since callbacks occur on the signaling thread, which may +// be a non-Java thread. +static JNIEnv* jni() { + return AttachCurrentThreadIfNeeded(); } -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()); - return Java_StatsReport_Constructor(env, j_id, j_type, report.timestamp(), - j_values); -} - -} // namespace - StatsObserverJni::StatsObserverJni(JNIEnv* jni, jobject j_observer) - : j_observer_global_(jni, 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")) {} void StatsObserverJni::OnComplete(const StatsReports& reports) { - JNIEnv* env = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(env); - 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); + 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; } } // namespace jni diff --git a/sdk/android/src/jni/pc/statsobserver_jni.h b/sdk/android/src/jni/pc/statsobserver_jni.h index ec5d4fdd70..d1e2224567 100644 --- a/sdk/android/src/jni/pc/statsobserver_jni.h +++ b/sdk/android/src/jni/pc/statsobserver_jni.h @@ -26,7 +26,16 @@ 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 2412649199..2566673dfe 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, - NativeToJavaString(jni, param.first), - NativeToJavaString(jni, param.second)); + JavaStringFromStdString(jni, param.first), + JavaStringFromStdString(jni, param.second)); } return jni->NewObject(video_codec_info_class, video_codec_info_constructor, - NativeToJavaString(jni, format.name), j_params); + JavaStringFromStdString(jni, format.name), j_params); } } // namespace jni diff --git a/sdk/android/src/jni/videodecoderfactorywrapper.cc b/sdk/android/src/jni/videodecoderfactorywrapper.cc index e687289ad3..cda9c4b483 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 = NativeToJavaString(jni, format.name); + jstring name = JavaStringFromStdString(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 30377db0a0..6b29c0eefe 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 = - JavaToNativeOptionalInt(env, j_decode_time_ms); + JavaIntegerToOptionalInt(env, j_decode_time_ms); rtc::Optional decoder_qp = - cast_optional(JavaToNativeOptionalInt(env, j_qp)); + cast_optional(JavaIntegerToOptionalInt(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 13b0e37c16..19c00ec371 100644 --- a/sdk/android/src/jni/videoencoderwrapper.cc +++ b/sdk/android/src/jni/videoencoderwrapper.cc @@ -121,7 +121,12 @@ int32_t VideoEncoderWrapper::Encode( ScopedLocalRefFrame local_ref_frame(jni); // Construct encode info. - jobjectArray j_frame_types = NativeToJavaFrameTypeArray(jni, *frame_types); + 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); + } jobject encode_info = Java_EncodeInfo_Constructor(jni, j_frame_types); FrameExtraInfo info; @@ -164,10 +169,10 @@ VideoEncoderWrapper::ScalingSettings VideoEncoderWrapper::GetScalingSettings() bool isOn = Java_VideoEncoderWrapper_getScalingSettingsOn(jni, j_scaling_settings); - rtc::Optional low = JavaToNativeOptionalInt( + rtc::Optional low = JavaIntegerToOptionalInt( jni, Java_VideoEncoderWrapper_getScalingSettingsLow(jni, j_scaling_settings)); - rtc::Optional high = JavaToNativeOptionalInt( + rtc::Optional high = JavaIntegerToOptionalInt( jni, Java_VideoEncoderWrapper_getScalingSettingsHigh(jni, j_scaling_settings)); @@ -195,7 +200,7 @@ void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni, std::vector buffer_copy(buffer_size); memcpy(buffer_copy.data(), buffer, buffer_size); - const int qp = JavaToNativeOptionalInt(jni, j_qp).value_or(-1); + const int qp = JavaIntegerToOptionalInt(jni, j_qp).value_or(-1); encoder_queue_->PostTask( [