1 /*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "sdk/android/src/jni/pc/peer_connection_factory.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "absl/memory/memory.h"
17 #include "api/video_codecs/video_decoder_factory.h"
18 #include "api/video_codecs/video_encoder_factory.h"
19 #include "media/base/media_engine.h"
20 #include "modules/audio_device/include/audio_device.h"
21 #include "modules/utility/include/jvm_android.h"
22 // We don't depend on the audio processing module implementation.
23 // The user may pass in a nullptr.
24 #include "api/call/call_factory_interface.h"
25 #include "api/rtc_event_log/rtc_event_log_factory.h"
26 #include "api/task_queue/default_task_queue_factory.h"
27 #include "api/video_codecs/video_decoder_factory.h"
28 #include "api/video_codecs/video_encoder_factory.h"
29 #include "media/engine/webrtc_media_engine.h"
30 #include "modules/audio_device/include/audio_device.h"
31 #include "modules/audio_processing/include/audio_processing.h"
32 #include "rtc_base/event_tracer.h"
33 #include "rtc_base/physical_socket_server.h"
34 #include "rtc_base/thread.h"
35 #include "sdk/android/generated_peerconnection_jni/PeerConnectionFactory_jni.h"
36 #include "sdk/android/native_api/jni/java_types.h"
37 #include "sdk/android/native_api/stacktrace/stacktrace.h"
38 #include "sdk/android/src/jni/jni_helpers.h"
39 #include "sdk/android/src/jni/logging/log_sink.h"
40 #include "sdk/android/src/jni/pc/android_network_monitor.h"
41 #include "sdk/android/src/jni/pc/audio.h"
42 #include "sdk/android/src/jni/pc/ice_candidate.h"
43 #include "sdk/android/src/jni/pc/owned_factory_and_threads.h"
44 #include "sdk/android/src/jni/pc/peer_connection.h"
45 #include "sdk/android/src/jni/pc/ssl_certificate_verifier_wrapper.h"
46 #include "sdk/android/src/jni/pc/video.h"
47 #include "system_wrappers/include/field_trial.h"
48
49 namespace webrtc {
50 namespace jni {
51
52 namespace {
53
54 // Take ownership of the jlong reference and cast it into an rtc::scoped_refptr.
55 template <typename T>
TakeOwnershipOfRefPtr(jlong j_pointer)56 rtc::scoped_refptr<T> TakeOwnershipOfRefPtr(jlong j_pointer) {
57 T* ptr = reinterpret_cast<T*>(j_pointer);
58 rtc::scoped_refptr<T> refptr;
59 refptr.swap(&ptr);
60 return refptr;
61 }
62
63 // Take ownership of the jlong reference and cast it into a std::unique_ptr.
64 template <typename T>
TakeOwnershipOfUniquePtr(jlong native_pointer)65 std::unique_ptr<T> TakeOwnershipOfUniquePtr(jlong native_pointer) {
66 return std::unique_ptr<T>(reinterpret_cast<T*>(native_pointer));
67 }
68
69 typedef void (*JavaMethodPointer)(JNIEnv*, const JavaRef<jobject>&);
70
71 // Post a message on the given thread that will call the Java method on the
72 // given Java object.
PostJavaCallback(JNIEnv * env,rtc::Thread * queue,const JavaRef<jobject> & j_object,JavaMethodPointer java_method_pointer)73 void PostJavaCallback(JNIEnv* env,
74 rtc::Thread* queue,
75 const JavaRef<jobject>& j_object,
76 JavaMethodPointer java_method_pointer) {
77 ScopedJavaGlobalRef<jobject> object(env, j_object);
78 queue->PostTask([object = std::move(object), java_method_pointer] {
79 java_method_pointer(AttachCurrentThreadIfNeeded(), object);
80 });
81 }
82
83 absl::optional<PeerConnectionFactoryInterface::Options>
JavaToNativePeerConnectionFactoryOptions(JNIEnv * jni,const JavaRef<jobject> & j_options)84 JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni,
85 const JavaRef<jobject>& j_options) {
86 if (j_options.is_null())
87 return absl::nullopt;
88
89 PeerConnectionFactoryInterface::Options native_options;
90
91 // This doesn't necessarily match the c++ version of this struct; feel free
92 // to add more parameters as necessary.
93 native_options.network_ignore_mask =
94 Java_Options_getNetworkIgnoreMask(jni, j_options);
95 native_options.disable_encryption =
96 Java_Options_getDisableEncryption(jni, j_options);
97 native_options.disable_network_monitor =
98 Java_Options_getDisableNetworkMonitor(jni, j_options);
99
100 return native_options;
101 }
102
103 // Place static objects into a container that gets leaked so we avoid
104 // non-trivial destructor.
105 struct StaticObjectContainer {
106 // Field trials initialization string
107 std::unique_ptr<std::string> field_trials_init_string;
108 // Set in PeerConnectionFactory_InjectLoggable().
109 std::unique_ptr<JNILogSink> jni_log_sink;
110 };
111
GetStaticObjects()112 StaticObjectContainer& GetStaticObjects() {
113 static StaticObjectContainer* static_objects = new StaticObjectContainer();
114 return *static_objects;
115 }
116
NativeToScopedJavaPeerConnectionFactory(JNIEnv * env,rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,std::unique_ptr<rtc::SocketFactory> socket_factory,std::unique_ptr<rtc::Thread> network_thread,std::unique_ptr<rtc::Thread> worker_thread,std::unique_ptr<rtc::Thread> signaling_thread)117 ScopedJavaLocalRef<jobject> NativeToScopedJavaPeerConnectionFactory(
118 JNIEnv* env,
119 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,
120 std::unique_ptr<rtc::SocketFactory> socket_factory,
121 std::unique_ptr<rtc::Thread> network_thread,
122 std::unique_ptr<rtc::Thread> worker_thread,
123 std::unique_ptr<rtc::Thread> signaling_thread) {
124 OwnedFactoryAndThreads* owned_factory = new OwnedFactoryAndThreads(
125 std::move(socket_factory), std::move(network_thread),
126 std::move(worker_thread), std::move(signaling_thread), pcf);
127
128 ScopedJavaLocalRef<jobject> j_pcf = Java_PeerConnectionFactory_Constructor(
129 env, NativeToJavaPointer(owned_factory));
130
131 PostJavaCallback(env, owned_factory->network_thread(), j_pcf,
132 &Java_PeerConnectionFactory_onNetworkThreadReady);
133 PostJavaCallback(env, owned_factory->worker_thread(), j_pcf,
134 &Java_PeerConnectionFactory_onWorkerThreadReady);
135 PostJavaCallback(env, owned_factory->signaling_thread(), j_pcf,
136 &Java_PeerConnectionFactory_onSignalingThreadReady);
137
138 return j_pcf;
139 }
140
PeerConnectionFactoryFromJava(jlong j_p)141 PeerConnectionFactoryInterface* PeerConnectionFactoryFromJava(jlong j_p) {
142 return reinterpret_cast<OwnedFactoryAndThreads*>(j_p)->factory();
143 }
144
145 } // namespace
146
147 // Note: Some of the video-specific PeerConnectionFactory methods are
148 // implemented in "video.cc". This is done so that if an application
149 // doesn't need video support, it can just link with "null_video.cc"
150 // instead of "video.cc", which doesn't bring in the video-specific
151 // dependencies.
152
153 // Set in PeerConnectionFactory_initializeAndroidGlobals().
154 static bool factory_static_initialized = false;
155
NativeToJavaPeerConnectionFactory(JNIEnv * jni,rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,std::unique_ptr<rtc::SocketFactory> socket_factory,std::unique_ptr<rtc::Thread> network_thread,std::unique_ptr<rtc::Thread> worker_thread,std::unique_ptr<rtc::Thread> signaling_thread)156 jobject NativeToJavaPeerConnectionFactory(
157 JNIEnv* jni,
158 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,
159 std::unique_ptr<rtc::SocketFactory> socket_factory,
160 std::unique_ptr<rtc::Thread> network_thread,
161 std::unique_ptr<rtc::Thread> worker_thread,
162 std::unique_ptr<rtc::Thread> signaling_thread) {
163 return NativeToScopedJavaPeerConnectionFactory(
164 jni, pcf, std::move(socket_factory), std::move(network_thread),
165 std::move(worker_thread), std::move(signaling_thread))
166 .Release();
167 }
168
JNI_PeerConnectionFactory_InitializeAndroidGlobals(JNIEnv * jni)169 static void JNI_PeerConnectionFactory_InitializeAndroidGlobals(JNIEnv* jni) {
170 if (!factory_static_initialized) {
171 JVM::Initialize(GetJVM());
172 factory_static_initialized = true;
173 }
174 }
175
JNI_PeerConnectionFactory_InitializeFieldTrials(JNIEnv * jni,const JavaParamRef<jstring> & j_trials_init_string)176 static void JNI_PeerConnectionFactory_InitializeFieldTrials(
177 JNIEnv* jni,
178 const JavaParamRef<jstring>& j_trials_init_string) {
179 std::unique_ptr<std::string>& field_trials_init_string =
180 GetStaticObjects().field_trials_init_string;
181
182 if (j_trials_init_string.is_null()) {
183 field_trials_init_string = nullptr;
184 field_trial::InitFieldTrialsFromString(nullptr);
185 return;
186 }
187 field_trials_init_string = std::make_unique<std::string>(
188 JavaToNativeString(jni, j_trials_init_string));
189 RTC_LOG(LS_INFO) << "initializeFieldTrials: " << *field_trials_init_string;
190 field_trial::InitFieldTrialsFromString(field_trials_init_string->c_str());
191 }
192
JNI_PeerConnectionFactory_InitializeInternalTracer(JNIEnv * jni)193 static void JNI_PeerConnectionFactory_InitializeInternalTracer(JNIEnv* jni) {
194 rtc::tracing::SetupInternalTracer();
195 }
196
197 static ScopedJavaLocalRef<jstring>
JNI_PeerConnectionFactory_FindFieldTrialsFullName(JNIEnv * jni,const JavaParamRef<jstring> & j_name)198 JNI_PeerConnectionFactory_FindFieldTrialsFullName(
199 JNIEnv* jni,
200 const JavaParamRef<jstring>& j_name) {
201 return NativeToJavaString(
202 jni, field_trial::FindFullName(JavaToStdString(jni, j_name)));
203 }
204
JNI_PeerConnectionFactory_StartInternalTracingCapture(JNIEnv * jni,const JavaParamRef<jstring> & j_event_tracing_filename)205 static jboolean JNI_PeerConnectionFactory_StartInternalTracingCapture(
206 JNIEnv* jni,
207 const JavaParamRef<jstring>& j_event_tracing_filename) {
208 if (j_event_tracing_filename.is_null())
209 return false;
210
211 const char* init_string =
212 jni->GetStringUTFChars(j_event_tracing_filename.obj(), NULL);
213 RTC_LOG(LS_INFO) << "Starting internal tracing to: " << init_string;
214 bool ret = rtc::tracing::StartInternalCapture(init_string);
215 jni->ReleaseStringUTFChars(j_event_tracing_filename.obj(), init_string);
216 return ret;
217 }
218
JNI_PeerConnectionFactory_StopInternalTracingCapture(JNIEnv * jni)219 static void JNI_PeerConnectionFactory_StopInternalTracingCapture(JNIEnv* jni) {
220 rtc::tracing::StopInternalCapture();
221 }
222
JNI_PeerConnectionFactory_ShutdownInternalTracer(JNIEnv * jni)223 static void JNI_PeerConnectionFactory_ShutdownInternalTracer(JNIEnv* jni) {
224 rtc::tracing::ShutdownInternalTracer();
225 }
226
227 // Following parameters are optional:
228 // `audio_device_module`, `jencoder_factory`, `jdecoder_factory`,
229 // `audio_processor`, `fec_controller_factory`,
230 // `network_state_predictor_factory`, `neteq_factory`.
CreatePeerConnectionFactoryForJava(JNIEnv * jni,const JavaParamRef<jobject> & jcontext,const JavaParamRef<jobject> & joptions,rtc::scoped_refptr<AudioDeviceModule> audio_device_module,rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,const JavaParamRef<jobject> & jencoder_factory,const JavaParamRef<jobject> & jdecoder_factory,rtc::scoped_refptr<AudioProcessing> audio_processor,std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory,std::unique_ptr<NetworkControllerFactoryInterface> network_controller_factory,std::unique_ptr<NetworkStatePredictorFactoryInterface> network_state_predictor_factory,std::unique_ptr<NetEqFactory> neteq_factory)231 ScopedJavaLocalRef<jobject> CreatePeerConnectionFactoryForJava(
232 JNIEnv* jni,
233 const JavaParamRef<jobject>& jcontext,
234 const JavaParamRef<jobject>& joptions,
235 rtc::scoped_refptr<AudioDeviceModule> audio_device_module,
236 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
237 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
238 const JavaParamRef<jobject>& jencoder_factory,
239 const JavaParamRef<jobject>& jdecoder_factory,
240 rtc::scoped_refptr<AudioProcessing> audio_processor,
241 std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory,
242 std::unique_ptr<NetworkControllerFactoryInterface>
243 network_controller_factory,
244 std::unique_ptr<NetworkStatePredictorFactoryInterface>
245 network_state_predictor_factory,
246 std::unique_ptr<NetEqFactory> neteq_factory) {
247 // talk/ assumes pretty widely that the current Thread is ThreadManager'd, but
248 // ThreadManager only WrapCurrentThread()s the thread where it is first
249 // created. Since the semantics around when auto-wrapping happens in
250 // webrtc/rtc_base/ are convoluted, we simply wrap here to avoid having to
251 // think about ramifications of auto-wrapping there.
252 rtc::ThreadManager::Instance()->WrapCurrentThread();
253
254 auto socket_server = std::make_unique<rtc::PhysicalSocketServer>();
255 auto network_thread = std::make_unique<rtc::Thread>(socket_server.get());
256 network_thread->SetName("network_thread", nullptr);
257 RTC_CHECK(network_thread->Start()) << "Failed to start thread";
258
259 std::unique_ptr<rtc::Thread> worker_thread = rtc::Thread::Create();
260 worker_thread->SetName("worker_thread", nullptr);
261 RTC_CHECK(worker_thread->Start()) << "Failed to start thread";
262
263 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
264 signaling_thread->SetName("signaling_thread", NULL);
265 RTC_CHECK(signaling_thread->Start()) << "Failed to start thread";
266
267 const absl::optional<PeerConnectionFactoryInterface::Options> options =
268 JavaToNativePeerConnectionFactoryOptions(jni, joptions);
269
270 PeerConnectionFactoryDependencies dependencies;
271 // TODO(bugs.webrtc.org/13145): Also add socket_server.get() to the
272 // dependencies.
273 dependencies.network_thread = network_thread.get();
274 dependencies.worker_thread = worker_thread.get();
275 dependencies.signaling_thread = signaling_thread.get();
276 dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
277 dependencies.call_factory = CreateCallFactory();
278 dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>(
279 dependencies.task_queue_factory.get());
280 dependencies.fec_controller_factory = std::move(fec_controller_factory);
281 dependencies.network_controller_factory =
282 std::move(network_controller_factory);
283 dependencies.network_state_predictor_factory =
284 std::move(network_state_predictor_factory);
285 dependencies.neteq_factory = std::move(neteq_factory);
286 if (!(options && options->disable_network_monitor)) {
287 dependencies.network_monitor_factory =
288 std::make_unique<AndroidNetworkMonitorFactory>();
289 }
290
291 cricket::MediaEngineDependencies media_dependencies;
292 media_dependencies.task_queue_factory = dependencies.task_queue_factory.get();
293 media_dependencies.adm = std::move(audio_device_module);
294 media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory);
295 media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory);
296 media_dependencies.audio_processing = std::move(audio_processor);
297 media_dependencies.video_encoder_factory =
298 absl::WrapUnique(CreateVideoEncoderFactory(jni, jencoder_factory));
299 media_dependencies.video_decoder_factory =
300 absl::WrapUnique(CreateVideoDecoderFactory(jni, jdecoder_factory));
301 dependencies.media_engine =
302 cricket::CreateMediaEngine(std::move(media_dependencies));
303
304 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory =
305 CreateModularPeerConnectionFactory(std::move(dependencies));
306
307 RTC_CHECK(factory) << "Failed to create the peer connection factory; "
308 "WebRTC/libjingle init likely failed on this device";
309 // TODO(honghaiz): Maybe put the options as the argument of
310 // CreatePeerConnectionFactory.
311 if (options)
312 factory->SetOptions(*options);
313
314 return NativeToScopedJavaPeerConnectionFactory(
315 jni, factory, std::move(socket_server), std::move(network_thread),
316 std::move(worker_thread), std::move(signaling_thread));
317 }
318
319 static ScopedJavaLocalRef<jobject>
JNI_PeerConnectionFactory_CreatePeerConnectionFactory(JNIEnv * jni,const JavaParamRef<jobject> & jcontext,const JavaParamRef<jobject> & joptions,jlong native_audio_device_module,jlong native_audio_encoder_factory,jlong native_audio_decoder_factory,const JavaParamRef<jobject> & jencoder_factory,const JavaParamRef<jobject> & jdecoder_factory,jlong native_audio_processor,jlong native_fec_controller_factory,jlong native_network_controller_factory,jlong native_network_state_predictor_factory,jlong native_neteq_factory)320 JNI_PeerConnectionFactory_CreatePeerConnectionFactory(
321 JNIEnv* jni,
322 const JavaParamRef<jobject>& jcontext,
323 const JavaParamRef<jobject>& joptions,
324 jlong native_audio_device_module,
325 jlong native_audio_encoder_factory,
326 jlong native_audio_decoder_factory,
327 const JavaParamRef<jobject>& jencoder_factory,
328 const JavaParamRef<jobject>& jdecoder_factory,
329 jlong native_audio_processor,
330 jlong native_fec_controller_factory,
331 jlong native_network_controller_factory,
332 jlong native_network_state_predictor_factory,
333 jlong native_neteq_factory) {
334 rtc::scoped_refptr<AudioProcessing> audio_processor(
335 reinterpret_cast<AudioProcessing*>(native_audio_processor));
336 return CreatePeerConnectionFactoryForJava(
337 jni, jcontext, joptions,
338 rtc::scoped_refptr<AudioDeviceModule>(
339 reinterpret_cast<AudioDeviceModule*>(native_audio_device_module)),
340 TakeOwnershipOfRefPtr<AudioEncoderFactory>(native_audio_encoder_factory),
341 TakeOwnershipOfRefPtr<AudioDecoderFactory>(native_audio_decoder_factory),
342 jencoder_factory, jdecoder_factory,
343 audio_processor ? audio_processor : CreateAudioProcessing(),
344 TakeOwnershipOfUniquePtr<FecControllerFactoryInterface>(
345 native_fec_controller_factory),
346 TakeOwnershipOfUniquePtr<NetworkControllerFactoryInterface>(
347 native_network_controller_factory),
348 TakeOwnershipOfUniquePtr<NetworkStatePredictorFactoryInterface>(
349 native_network_state_predictor_factory),
350 TakeOwnershipOfUniquePtr<NetEqFactory>(native_neteq_factory));
351 }
352
JNI_PeerConnectionFactory_FreeFactory(JNIEnv *,jlong j_p)353 static void JNI_PeerConnectionFactory_FreeFactory(JNIEnv*,
354 jlong j_p) {
355 delete reinterpret_cast<OwnedFactoryAndThreads*>(j_p);
356 field_trial::InitFieldTrialsFromString(nullptr);
357 GetStaticObjects().field_trials_init_string = nullptr;
358 }
359
JNI_PeerConnectionFactory_CreateLocalMediaStream(JNIEnv * jni,jlong native_factory,const JavaParamRef<jstring> & label)360 static jlong JNI_PeerConnectionFactory_CreateLocalMediaStream(
361 JNIEnv* jni,
362 jlong native_factory,
363 const JavaParamRef<jstring>& label) {
364 rtc::scoped_refptr<MediaStreamInterface> stream(
365 PeerConnectionFactoryFromJava(native_factory)
366 ->CreateLocalMediaStream(JavaToStdString(jni, label)));
367 return jlongFromPointer(stream.release());
368 }
369
JNI_PeerConnectionFactory_CreateAudioSource(JNIEnv * jni,jlong native_factory,const JavaParamRef<jobject> & j_constraints)370 static jlong JNI_PeerConnectionFactory_CreateAudioSource(
371 JNIEnv* jni,
372 jlong native_factory,
373 const JavaParamRef<jobject>& j_constraints) {
374 std::unique_ptr<MediaConstraints> constraints =
375 JavaToNativeMediaConstraints(jni, j_constraints);
376 cricket::AudioOptions options;
377 CopyConstraintsIntoAudioOptions(constraints.get(), &options);
378 rtc::scoped_refptr<AudioSourceInterface> source(
379 PeerConnectionFactoryFromJava(native_factory)
380 ->CreateAudioSource(options));
381 return jlongFromPointer(source.release());
382 }
383
JNI_PeerConnectionFactory_CreateAudioTrack(JNIEnv * jni,jlong native_factory,const JavaParamRef<jstring> & id,jlong native_source)384 jlong JNI_PeerConnectionFactory_CreateAudioTrack(
385 JNIEnv* jni,
386 jlong native_factory,
387 const JavaParamRef<jstring>& id,
388 jlong native_source) {
389 rtc::scoped_refptr<AudioTrackInterface> track(
390 PeerConnectionFactoryFromJava(native_factory)
391 ->CreateAudioTrack(
392 JavaToStdString(jni, id),
393 reinterpret_cast<AudioSourceInterface*>(native_source)));
394 return jlongFromPointer(track.release());
395 }
396
JNI_PeerConnectionFactory_StartAecDump(JNIEnv * jni,jlong native_factory,jint file_descriptor,jint filesize_limit_bytes)397 static jboolean JNI_PeerConnectionFactory_StartAecDump(
398 JNIEnv* jni,
399 jlong native_factory,
400 jint file_descriptor,
401 jint filesize_limit_bytes) {
402 FILE* f = fdopen(file_descriptor, "wb");
403 if (!f) {
404 close(file_descriptor);
405 return false;
406 }
407
408 return PeerConnectionFactoryFromJava(native_factory)
409 ->StartAecDump(f, filesize_limit_bytes);
410 }
411
JNI_PeerConnectionFactory_StopAecDump(JNIEnv * jni,jlong native_factory)412 static void JNI_PeerConnectionFactory_StopAecDump(JNIEnv* jni,
413 jlong native_factory) {
414 PeerConnectionFactoryFromJava(native_factory)->StopAecDump();
415 }
416
JNI_PeerConnectionFactory_CreatePeerConnection(JNIEnv * jni,jlong factory,const JavaParamRef<jobject> & j_rtc_config,const JavaParamRef<jobject> & j_constraints,jlong observer_p,const JavaParamRef<jobject> & j_sslCertificateVerifier)417 static jlong JNI_PeerConnectionFactory_CreatePeerConnection(
418 JNIEnv* jni,
419 jlong factory,
420 const JavaParamRef<jobject>& j_rtc_config,
421 const JavaParamRef<jobject>& j_constraints,
422 jlong observer_p,
423 const JavaParamRef<jobject>& j_sslCertificateVerifier) {
424 std::unique_ptr<PeerConnectionObserver> observer(
425 reinterpret_cast<PeerConnectionObserver*>(observer_p));
426
427 PeerConnectionInterface::RTCConfiguration rtc_config(
428 PeerConnectionInterface::RTCConfigurationType::kAggressive);
429 JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
430
431 if (rtc_config.certificates.empty()) {
432 // Generate non-default certificate.
433 rtc::KeyType key_type = GetRtcConfigKeyType(jni, j_rtc_config);
434 if (key_type != rtc::KT_DEFAULT) {
435 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
436 rtc::RTCCertificateGenerator::GenerateCertificate(
437 rtc::KeyParams(key_type), absl::nullopt);
438 if (!certificate) {
439 RTC_LOG(LS_ERROR) << "Failed to generate certificate. KeyType: "
440 << key_type;
441 return 0;
442 }
443 rtc_config.certificates.push_back(certificate);
444 }
445 }
446
447 std::unique_ptr<MediaConstraints> constraints;
448 if (!j_constraints.is_null()) {
449 constraints = JavaToNativeMediaConstraints(jni, j_constraints);
450 CopyConstraintsIntoRtcConfiguration(constraints.get(), &rtc_config);
451 }
452
453 PeerConnectionDependencies peer_connection_dependencies(observer.get());
454 if (!j_sslCertificateVerifier.is_null()) {
455 peer_connection_dependencies.tls_cert_verifier =
456 std::make_unique<SSLCertificateVerifierWrapper>(
457 jni, j_sslCertificateVerifier);
458 }
459
460 auto result =
461 PeerConnectionFactoryFromJava(factory)->CreatePeerConnectionOrError(
462 rtc_config, std::move(peer_connection_dependencies));
463 if (!result.ok())
464 return 0;
465
466 return jlongFromPointer(new OwnedPeerConnection(
467 result.MoveValue(), std::move(observer), std::move(constraints)));
468 }
469
JNI_PeerConnectionFactory_CreateVideoSource(JNIEnv * jni,jlong native_factory,jboolean is_screencast,jboolean align_timestamps)470 static jlong JNI_PeerConnectionFactory_CreateVideoSource(
471 JNIEnv* jni,
472 jlong native_factory,
473 jboolean is_screencast,
474 jboolean align_timestamps) {
475 OwnedFactoryAndThreads* factory =
476 reinterpret_cast<OwnedFactoryAndThreads*>(native_factory);
477 return jlongFromPointer(CreateVideoSource(jni, factory->signaling_thread(),
478 factory->worker_thread(),
479 is_screencast, align_timestamps));
480 }
481
JNI_PeerConnectionFactory_CreateVideoTrack(JNIEnv * jni,jlong native_factory,const JavaParamRef<jstring> & id,jlong native_source)482 static jlong JNI_PeerConnectionFactory_CreateVideoTrack(
483 JNIEnv* jni,
484 jlong native_factory,
485 const JavaParamRef<jstring>& id,
486 jlong native_source) {
487 rtc::scoped_refptr<VideoTrackInterface> track =
488 PeerConnectionFactoryFromJava(native_factory)
489 ->CreateVideoTrack(
490 JavaToStdString(jni, id),
491 reinterpret_cast<VideoTrackSourceInterface*>(native_source));
492 return jlongFromPointer(track.release());
493 }
494
JNI_PeerConnectionFactory_GetNativePeerConnectionFactory(JNIEnv * jni,jlong native_factory)495 static jlong JNI_PeerConnectionFactory_GetNativePeerConnectionFactory(
496 JNIEnv* jni,
497 jlong native_factory) {
498 return jlongFromPointer(PeerConnectionFactoryFromJava(native_factory));
499 }
500
JNI_PeerConnectionFactory_InjectLoggable(JNIEnv * jni,const JavaParamRef<jobject> & j_logging,jint nativeSeverity)501 static void JNI_PeerConnectionFactory_InjectLoggable(
502 JNIEnv* jni,
503 const JavaParamRef<jobject>& j_logging,
504 jint nativeSeverity) {
505 std::unique_ptr<JNILogSink>& jni_log_sink = GetStaticObjects().jni_log_sink;
506
507 // If there is already a LogSink, remove it from LogMessage.
508 if (jni_log_sink) {
509 rtc::LogMessage::RemoveLogToStream(jni_log_sink.get());
510 }
511 jni_log_sink = std::make_unique<JNILogSink>(jni, j_logging);
512 rtc::LogMessage::AddLogToStream(
513 jni_log_sink.get(), static_cast<rtc::LoggingSeverity>(nativeSeverity));
514 rtc::LogMessage::LogToDebug(rtc::LS_NONE);
515 }
516
JNI_PeerConnectionFactory_DeleteLoggable(JNIEnv * jni)517 static void JNI_PeerConnectionFactory_DeleteLoggable(JNIEnv* jni) {
518 std::unique_ptr<JNILogSink>& jni_log_sink = GetStaticObjects().jni_log_sink;
519
520 if (jni_log_sink) {
521 rtc::LogMessage::RemoveLogToStream(jni_log_sink.get());
522 jni_log_sink.reset();
523 }
524 }
525
JNI_PeerConnectionFactory_PrintStackTrace(JNIEnv * env,jint tid)526 static void JNI_PeerConnectionFactory_PrintStackTrace(JNIEnv* env, jint tid) {
527 RTC_LOG(LS_WARNING) << StackTraceToString(GetStackTrace(tid));
528 }
529
530 } // namespace jni
531 } // namespace webrtc
532