From 80610c4fd18da5bc3e85c62262976914ceb2c5ff Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Sat, 25 Nov 2017 21:18:34 +0100 Subject: [PATCH] Android: Generate JNI code for IceCandidate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:8278 Change-Id: I4facd1f6babd6e8a9b35c86b6ad7420e52321f49 Reviewed-on: https://webrtc-review.googlesource.com/25960 Reviewed-by: Sami Kalliomäki Commit-Queue: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#20888} --- sdk/android/BUILD.gn | 1 + sdk/android/api/org/webrtc/IceCandidate.java | 19 ++++++- sdk/android/src/jni/classreferenceholder.cc | 1 - .../src/jni/pc/java_native_conversion.cc | 54 +++++++++++-------- .../src/jni/pc/java_native_conversion.h | 7 +-- .../src/jni/pc/peerconnectionobserver_jni.cc | 23 +++----- 6 files changed, 62 insertions(+), 43 deletions(-) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 77b5493d4f..0be6195271 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -285,6 +285,7 @@ rtc_static_library("null_media_jni") { generate_jni("generated_peerconnection_jni") { sources = [ "api/org/webrtc/DataChannel.java", + "api/org/webrtc/IceCandidate.java", "api/org/webrtc/MediaConstraints.java", "api/org/webrtc/NetworkMonitor.java", "api/org/webrtc/NetworkMonitorAutoDetect.java", diff --git a/sdk/android/api/org/webrtc/IceCandidate.java b/sdk/android/api/org/webrtc/IceCandidate.java index b03f1a3677..51865e9f16 100644 --- a/sdk/android/api/org/webrtc/IceCandidate.java +++ b/sdk/android/api/org/webrtc/IceCandidate.java @@ -27,8 +27,8 @@ public class IceCandidate { this.serverUrl = ""; } - // Only be called internally from JNI. - private IceCandidate(String sdpMid, int sdpMLineIndex, String sdp, String serverUrl) { + @CalledByNative + IceCandidate(String sdpMid, int sdpMLineIndex, String sdp, String serverUrl) { this.sdpMid = sdpMid; this.sdpMLineIndex = sdpMLineIndex; this.sdp = sdp; @@ -39,4 +39,19 @@ public class IceCandidate { public String toString() { return sdpMid + ":" + sdpMLineIndex + ":" + sdp + ":" + serverUrl; } + + @CalledByNative + String getSdpMid() { + return sdpMid; + } + + @CalledByNative + String getSdp() { + return sdp; + } + + @CalledByNative + static IceCandidate[] createArray(int size) { + return new IceCandidate[size]; + } } diff --git a/sdk/android/src/jni/classreferenceholder.cc b/sdk/android/src/jni/classreferenceholder.cc index 1187d3e41d..f578c475f7 100644 --- a/sdk/android/src/jni/classreferenceholder.cc +++ b/sdk/android/src/jni/classreferenceholder.cc @@ -68,7 +68,6 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) { LoadClass(jni, "org/webrtc/EglBase14$Context"); LoadClass(jni, "org/webrtc/EncodedImage"); LoadClass(jni, "org/webrtc/EncodedImage$FrameType"); - LoadClass(jni, "org/webrtc/IceCandidate"); LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder"); LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer"); LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer"); diff --git a/sdk/android/src/jni/pc/java_native_conversion.cc b/sdk/android/src/jni/pc/java_native_conversion.cc index 56a1f4efc6..ca9bbfb39a 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.cc +++ b/sdk/android/src/jni/pc/java_native_conversion.cc @@ -13,11 +13,27 @@ #include #include "pc/webrtcsdp.h" +#include "sdk/android/generated_peerconnection_jni/jni/IceCandidate_jni.h" #include "sdk/android/src/jni/classreferenceholder.h" namespace webrtc { 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) { + return Java_IceCandidate_Constructor( + env, JavaStringFromStdString(env, sdp_mid), sdp_mline_index, + JavaStringFromStdString(env, sdp), + JavaStringFromStdString(env, server_url)); +} + +} // namespace + jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) { jclass j_media_type_class = FindClass(jni, "org/webrtc/MediaStreamTrack$MediaType"); @@ -58,15 +74,10 @@ cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type) { } cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) { - jclass j_candidate_class = GetObjectClass(jni, j_candidate); - jfieldID j_sdp_mid_id = - GetFieldID(jni, j_candidate_class, "sdpMid", "Ljava/lang/String;"); std::string sdp_mid = - JavaToStdString(jni, GetStringField(jni, j_candidate, j_sdp_mid_id)); - jfieldID j_sdp_id = - GetFieldID(jni, j_candidate_class, "sdp", "Ljava/lang/String;"); + JavaToStdString(jni, Java_IceCandidate_getSdpMid(jni, j_candidate)); std::string sdp = - JavaToStdString(jni, GetStringField(jni, j_candidate, j_sdp_id)); + JavaToStdString(jni, Java_IceCandidate_getSdp(jni, j_candidate)); cricket::Candidate candidate; if (!SdpDeserializeCandidate(sdp_mid, sdp, &candidate, NULL)) { RTC_LOG(LS_ERROR) << "SdpDescrializeCandidate failed with sdp " << sdp; @@ -74,32 +85,33 @@ cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) { return candidate; } -jobject NativeToJavaCandidate(JNIEnv* jni, - jclass* candidate_class, +jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate) { std::string sdp = SdpSerializeCandidate(candidate); RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate"; - jmethodID ctor = GetMethodID(jni, *candidate_class, "", - "(Ljava/lang/String;ILjava/lang/String;)V"); - jstring j_mid = JavaStringFromStdString(jni, candidate.transport_name()); - jstring j_sdp = JavaStringFromStdString(jni, sdp); // sdp_mline_index is not used, pass an invalid value -1. - jobject j_candidate = - jni->NewObject(*candidate_class, ctor, j_mid, -1, j_sdp); - CHECK_EXCEPTION(jni) << "error during Java Candidate NewObject"; - return j_candidate; + return NativeToJavaCandidate(env, candidate.transport_name(), + -1 /* sdp_mline_index */, sdp, + "" /* server_url */); +} + +jobject NativeToJavaCandidate(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()); } jobjectArray NativeToJavaCandidateArray( JNIEnv* jni, const std::vector& candidates) { - jclass candidate_class = FindClass(jni, "org/webrtc/IceCandidate"); jobjectArray java_candidates = - jni->NewObjectArray(candidates.size(), candidate_class, NULL); + Java_IceCandidate_createArray(jni, candidates.size()); int i = 0; for (const cricket::Candidate& candidate : candidates) { - jobject j_candidate = - NativeToJavaCandidate(jni, &candidate_class, candidate); + jobject j_candidate = NativeToJavaCandidate(jni, candidate); jni->SetObjectArrayElement(java_candidates, i++, j_candidate); } return java_candidates; diff --git a/sdk/android/src/jni/pc/java_native_conversion.h b/sdk/android/src/jni/pc/java_native_conversion.h index 9b74ad3f91..cb9f861991 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.h +++ b/sdk/android/src/jni/pc/java_native_conversion.h @@ -36,9 +36,10 @@ jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type); cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate); -jobject NativeToJavaCandidate(JNIEnv* jni, - jclass* candidate_class, - const cricket::Candidate& candidate); +jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate); + +jobject NativeToJavaCandidate(JNIEnv* env, + const IceCandidateInterface& candidate); jobjectArray NativeToJavaCandidateArray( JNIEnv* jni, diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc index 03436de47b..8bb098ef6c 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc @@ -61,23 +61,14 @@ PeerConnectionObserverJni::~PeerConnectionObserverJni() { void PeerConnectionObserverJni::OnIceCandidate( const IceCandidateInterface* candidate) { - ScopedLocalRefFrame local_ref_frame(jni()); - std::string sdp; - RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; - jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate"); - jmethodID ctor = - GetMethodID(jni(), candidate_class, "", - "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"); - jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid()); - jstring j_sdp = JavaStringFromStdString(jni(), sdp); - jstring j_url = JavaStringFromStdString(jni(), candidate->candidate().url()); - jobject j_candidate = jni()->NewObject( - candidate_class, ctor, j_mid, candidate->sdp_mline_index(), j_sdp, j_url); - CHECK_EXCEPTION(jni()) << "error during NewObject"; - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceCandidate", + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + jobject j_candidate = NativeToJavaCandidate(env, *candidate); + + jmethodID m = GetMethodID(env, *j_observer_class_, "onIceCandidate", "(Lorg/webrtc/IceCandidate;)V"); - jni()->CallVoidMethod(*j_observer_global_, m, j_candidate); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + env->CallVoidMethod(*j_observer_global_, m, j_candidate); + CHECK_EXCEPTION(env) << "error during CallVoidMethod"; } void PeerConnectionObserverJni::OnIceCandidatesRemoved(