Android: Generate JNI code for IceCandidate

Bug: webrtc:8278
Change-Id: I4facd1f6babd6e8a9b35c86b6ad7420e52321f49
Reviewed-on: https://webrtc-review.googlesource.com/25960
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20888}
This commit is contained in:
Magnus Jedvert
2017-11-25 21:18:34 +01:00
committed by Commit Bot
parent 5b8c0a2a1e
commit 80610c4fd1
6 changed files with 62 additions and 43 deletions

View File

@ -285,6 +285,7 @@ rtc_static_library("null_media_jni") {
generate_jni("generated_peerconnection_jni") { generate_jni("generated_peerconnection_jni") {
sources = [ sources = [
"api/org/webrtc/DataChannel.java", "api/org/webrtc/DataChannel.java",
"api/org/webrtc/IceCandidate.java",
"api/org/webrtc/MediaConstraints.java", "api/org/webrtc/MediaConstraints.java",
"api/org/webrtc/NetworkMonitor.java", "api/org/webrtc/NetworkMonitor.java",
"api/org/webrtc/NetworkMonitorAutoDetect.java", "api/org/webrtc/NetworkMonitorAutoDetect.java",

View File

@ -27,8 +27,8 @@ public class IceCandidate {
this.serverUrl = ""; this.serverUrl = "";
} }
// Only be called internally from JNI. @CalledByNative
private IceCandidate(String sdpMid, int sdpMLineIndex, String sdp, String serverUrl) { IceCandidate(String sdpMid, int sdpMLineIndex, String sdp, String serverUrl) {
this.sdpMid = sdpMid; this.sdpMid = sdpMid;
this.sdpMLineIndex = sdpMLineIndex; this.sdpMLineIndex = sdpMLineIndex;
this.sdp = sdp; this.sdp = sdp;
@ -39,4 +39,19 @@ public class IceCandidate {
public String toString() { public String toString() {
return sdpMid + ":" + sdpMLineIndex + ":" + sdp + ":" + serverUrl; 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];
}
} }

View File

@ -68,7 +68,6 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "org/webrtc/EglBase14$Context"); LoadClass(jni, "org/webrtc/EglBase14$Context");
LoadClass(jni, "org/webrtc/EncodedImage"); LoadClass(jni, "org/webrtc/EncodedImage");
LoadClass(jni, "org/webrtc/EncodedImage$FrameType"); LoadClass(jni, "org/webrtc/EncodedImage$FrameType");
LoadClass(jni, "org/webrtc/IceCandidate");
LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder"); LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder");
LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer"); LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer");
LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer"); LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer");

View File

@ -13,11 +13,27 @@
#include <string> #include <string>
#include "pc/webrtcsdp.h" #include "pc/webrtcsdp.h"
#include "sdk/android/generated_peerconnection_jni/jni/IceCandidate_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/src/jni/classreferenceholder.h"
namespace webrtc { namespace webrtc {
namespace jni { 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) { jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) {
jclass j_media_type_class = jclass j_media_type_class =
FindClass(jni, "org/webrtc/MediaStreamTrack$MediaType"); 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) { 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 = std::string sdp_mid =
JavaToStdString(jni, GetStringField(jni, j_candidate, j_sdp_mid_id)); JavaToStdString(jni, Java_IceCandidate_getSdpMid(jni, j_candidate));
jfieldID j_sdp_id =
GetFieldID(jni, j_candidate_class, "sdp", "Ljava/lang/String;");
std::string sdp = std::string sdp =
JavaToStdString(jni, GetStringField(jni, j_candidate, j_sdp_id)); JavaToStdString(jni, Java_IceCandidate_getSdp(jni, j_candidate));
cricket::Candidate candidate; cricket::Candidate candidate;
if (!SdpDeserializeCandidate(sdp_mid, sdp, &candidate, NULL)) { if (!SdpDeserializeCandidate(sdp_mid, sdp, &candidate, NULL)) {
RTC_LOG(LS_ERROR) << "SdpDescrializeCandidate failed with sdp " << sdp; RTC_LOG(LS_ERROR) << "SdpDescrializeCandidate failed with sdp " << sdp;
@ -74,32 +85,33 @@ cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) {
return candidate; return candidate;
} }
jobject NativeToJavaCandidate(JNIEnv* jni, jobject NativeToJavaCandidate(JNIEnv* env,
jclass* candidate_class,
const cricket::Candidate& candidate) { const cricket::Candidate& candidate) {
std::string sdp = SdpSerializeCandidate(candidate); std::string sdp = SdpSerializeCandidate(candidate);
RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate"; RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate";
jmethodID ctor = GetMethodID(jni, *candidate_class, "<init>",
"(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. // sdp_mline_index is not used, pass an invalid value -1.
jobject j_candidate = return NativeToJavaCandidate(env, candidate.transport_name(),
jni->NewObject(*candidate_class, ctor, j_mid, -1, j_sdp); -1 /* sdp_mline_index */, sdp,
CHECK_EXCEPTION(jni) << "error during Java Candidate NewObject"; "" /* server_url */);
return j_candidate; }
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( jobjectArray NativeToJavaCandidateArray(
JNIEnv* jni, JNIEnv* jni,
const std::vector<cricket::Candidate>& candidates) { const std::vector<cricket::Candidate>& candidates) {
jclass candidate_class = FindClass(jni, "org/webrtc/IceCandidate");
jobjectArray java_candidates = jobjectArray java_candidates =
jni->NewObjectArray(candidates.size(), candidate_class, NULL); Java_IceCandidate_createArray(jni, candidates.size());
int i = 0; int i = 0;
for (const cricket::Candidate& candidate : candidates) { for (const cricket::Candidate& candidate : candidates) {
jobject j_candidate = jobject j_candidate = NativeToJavaCandidate(jni, candidate);
NativeToJavaCandidate(jni, &candidate_class, candidate);
jni->SetObjectArrayElement(java_candidates, i++, j_candidate); jni->SetObjectArrayElement(java_candidates, i++, j_candidate);
} }
return java_candidates; return java_candidates;

View File

@ -36,9 +36,10 @@ jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type);
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate); cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate);
jobject NativeToJavaCandidate(JNIEnv* jni, jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate);
jclass* candidate_class,
const cricket::Candidate& candidate); jobject NativeToJavaCandidate(JNIEnv* env,
const IceCandidateInterface& candidate);
jobjectArray NativeToJavaCandidateArray( jobjectArray NativeToJavaCandidateArray(
JNIEnv* jni, JNIEnv* jni,

View File

@ -61,23 +61,14 @@ PeerConnectionObserverJni::~PeerConnectionObserverJni() {
void PeerConnectionObserverJni::OnIceCandidate( void PeerConnectionObserverJni::OnIceCandidate(
const IceCandidateInterface* candidate) { const IceCandidateInterface* candidate) {
ScopedLocalRefFrame local_ref_frame(jni()); JNIEnv* env = AttachCurrentThreadIfNeeded();
std::string sdp; ScopedLocalRefFrame local_ref_frame(env);
RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; jobject j_candidate = NativeToJavaCandidate(env, *candidate);
jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate");
jmethodID ctor = jmethodID m = GetMethodID(env, *j_observer_class_, "onIceCandidate",
GetMethodID(jni(), candidate_class, "<init>",
"(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",
"(Lorg/webrtc/IceCandidate;)V"); "(Lorg/webrtc/IceCandidate;)V");
jni()->CallVoidMethod(*j_observer_global_, m, j_candidate); env->CallVoidMethod(*j_observer_global_, m, j_candidate);
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; CHECK_EXCEPTION(env) << "error during CallVoidMethod";
} }
void PeerConnectionObserverJni::OnIceCandidatesRemoved( void PeerConnectionObserverJni::OnIceCandidatesRemoved(