Make Android/iOS local/remote description accessors thread safe.

Since the descriptions can be modified on the signaling thread,
ToString can only be safely called on that thread.

Bug: webrtc:11791
Change-Id: Icf6aada8aa66d00be94c6bda7b22e41b5d3bbc17
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180541
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Commit-Queue: Taylor <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31862}
This commit is contained in:
Taylor Brandstetter
2020-08-03 16:36:16 -07:00
committed by Commit Bot
parent 491fa44ed9
commit c88fe70a8d
12 changed files with 87 additions and 34 deletions

View File

@ -478,17 +478,39 @@ static jlong JNI_PeerConnection_GetNativePeerConnection(
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetLocalDescription(
JNIEnv* jni,
const JavaParamRef<jobject>& j_pc) {
const SessionDescriptionInterface* sdp =
ExtractNativePC(jni, j_pc)->local_description();
return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
PeerConnectionInterface* pc = ExtractNativePC(jni, j_pc);
// It's only safe to operate on SessionDescriptionInterface on the
// signaling thread, but |jni| may only be used on the current thread, so we
// must do this odd dance.
std::string sdp;
std::string type;
pc->signaling_thread()->Invoke<void>(RTC_FROM_HERE, [pc, &sdp, &type] {
const SessionDescriptionInterface* desc = pc->local_description();
if (desc) {
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
type = desc->type();
}
});
return sdp.empty() ? nullptr : NativeToJavaSessionDescription(jni, sdp, type);
}
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetRemoteDescription(
JNIEnv* jni,
const JavaParamRef<jobject>& j_pc) {
const SessionDescriptionInterface* sdp =
ExtractNativePC(jni, j_pc)->remote_description();
return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
PeerConnectionInterface* pc = ExtractNativePC(jni, j_pc);
// It's only safe to operate on SessionDescriptionInterface on the
// signaling thread, but |jni| may only be used on the current thread, so we
// must do this odd dance.
std::string sdp;
std::string type;
pc->signaling_thread()->Invoke<void>(RTC_FROM_HERE, [pc, &sdp, &type] {
const SessionDescriptionInterface* desc = pc->remote_description();
if (desc) {
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
type = desc->type();
}
});
return sdp.empty() ? nullptr : NativeToJavaSessionDescription(jni, sdp, type);
}
static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetCertificate(

View File

@ -31,8 +31,11 @@ CreateSdpObserverJni::~CreateSdpObserverJni() = default;
void CreateSdpObserverJni::OnSuccess(SessionDescriptionInterface* desc) {
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_SdpObserver_onCreateSuccess(env, j_observer_global_,
NativeToJavaSessionDescription(env, desc));
std::string sdp;
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
Java_SdpObserver_onCreateSuccess(
env, j_observer_global_,
NativeToJavaSessionDescription(env, sdp, desc->type()));
// OnSuccess transfers ownership of the description (there's a TODO to make
// it use unique_ptr...).
delete desc;

View File

@ -37,12 +37,10 @@ std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
ScopedJavaLocalRef<jobject> NativeToJavaSessionDescription(
JNIEnv* jni,
const SessionDescriptionInterface* desc) {
std::string sdp;
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
const std::string& sdp,
const std::string& type) {
return Java_SessionDescription_Constructor(
jni,
Java_Type_fromCanonicalForm(jni, NativeToJavaString(jni, desc->type())),
jni, Java_Type_fromCanonicalForm(jni, NativeToJavaString(jni, type)),
NativeToJavaString(jni, sdp));
}

View File

@ -13,6 +13,7 @@
#include <jni.h>
#include <memory>
#include <string>
#include "api/jsep.h"
#include "sdk/android/native_api/jni/scoped_java_ref.h"
@ -26,7 +27,8 @@ std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
ScopedJavaLocalRef<jobject> NativeToJavaSessionDescription(
JNIEnv* jni,
const SessionDescriptionInterface* desc);
const std::string& sdp,
const std::string& type);
} // namespace jni
} // namespace webrtc