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/system/thread_registry.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 rtc::Location & posted_from,const JavaRef<jobject> & j_object,JavaMethodPointer java_method_pointer)73 void PostJavaCallback(JNIEnv* env,
74 rtc::Thread* queue,
75 const rtc::Location& posted_from,
76 const JavaRef<jobject>& j_object,
77 JavaMethodPointer java_method_pointer) {
78 // One-off message handler that calls the Java method on the specified Java
79 // object before deleting itself.
80 class JavaAsyncCallback : public rtc::MessageHandler {
81 public:
82 JavaAsyncCallback(JNIEnv* env,
83 const JavaRef<jobject>& j_object,
84 JavaMethodPointer java_method_pointer)
85 : j_object_(env, j_object), java_method_pointer_(java_method_pointer) {}
86
87 void OnMessage(rtc::Message*) override {
88 java_method_pointer_(AttachCurrentThreadIfNeeded(), j_object_);
89 // The message has been delivered, clean up after ourself.
90 delete this;
91 }
92
93 private:
94 ScopedJavaGlobalRef<jobject> j_object_;
95 JavaMethodPointer java_method_pointer_;
96 };
97
98 queue->Post(posted_from,
99 new JavaAsyncCallback(env, j_object, java_method_pointer));
100 }
101
102 absl::optional<PeerConnectionFactoryInterface::Options>
JavaToNativePeerConnectionFactoryOptions(JNIEnv * jni,const JavaRef<jobject> & j_options)103 JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni,
104 const JavaRef<jobject>& j_options) {
105 if (j_options.is_null())
106 return absl::nullopt;
107
108 PeerConnectionFactoryInterface::Options native_options;
109
110 // This doesn't necessarily match the c++ version of this struct; feel free
111 // to add more parameters as necessary.
112 native_options.network_ignore_mask =
113 Java_Options_getNetworkIgnoreMask(jni, j_options);
114 native_options.disable_encryption =
115 Java_Options_getDisableEncryption(jni, j_options);
116 native_options.disable_network_monitor =
117 Java_Options_getDisableNetworkMonitor(jni, j_options);
118
119 return native_options;
120 }
121
122 // Place static objects into a container that gets leaked so we avoid
123 // non-trivial destructor.
124 struct StaticObjectContainer {
125 // Field trials initialization string
126 std::unique_ptr<std::string> field_trials_init_string;
127 // Set in PeerConnectionFactory_InjectLoggable().
128 std::unique_ptr<JNILogSink> jni_log_sink;
129 };
130
GetStaticObjects()131 StaticObjectContainer& GetStaticObjects() {
132 static StaticObjectContainer* static_objects = new StaticObjectContainer();
133 return *static_objects;
134 }
135
NativeToScopedJavaPeerConnectionFactory(JNIEnv * env,rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,std::unique_ptr<rtc::Thread> network_thread,std::unique_ptr<rtc::Thread> worker_thread,std::unique_ptr<rtc::Thread> signaling_thread)136 ScopedJavaLocalRef<jobject> NativeToScopedJavaPeerConnectionFactory(
137 JNIEnv* env,
138 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,
139 std::unique_ptr<rtc::Thread> network_thread,
140 std::unique_ptr<rtc::Thread> worker_thread,
141 std::unique_ptr<rtc::Thread> signaling_thread) {
142 OwnedFactoryAndThreads* owned_factory = new OwnedFactoryAndThreads(
143 std::move(network_thread), std::move(worker_thread),
144 std::move(signaling_thread), pcf);
145
146 ScopedJavaLocalRef<jobject> j_pcf = Java_PeerConnectionFactory_Constructor(
147 env, NativeToJavaPointer(owned_factory));
148
149 PostJavaCallback(env, owned_factory->network_thread(), RTC_FROM_HERE, j_pcf,
150 &Java_PeerConnectionFactory_onNetworkThreadReady);
151 PostJavaCallback(env, owned_factory->worker_thread(), RTC_FROM_HERE, j_pcf,
152 &Java_PeerConnectionFactory_onWorkerThreadReady);
153 PostJavaCallback(env, owned_factory->signaling_thread(), RTC_FROM_HERE, j_pcf,
154 &Java_PeerConnectionFactory_onSignalingThreadReady);
155
156 return j_pcf;
157 }
158
PeerConnectionFactoryFromJava(jlong j_p)159 PeerConnectionFactoryInterface* PeerConnectionFactoryFromJava(jlong j_p) {
160 return reinterpret_cast<OwnedFactoryAndThreads*>(j_p)->factory();
161 }
162
163 } // namespace
164
165 // Note: Some of the video-specific PeerConnectionFactory methods are
166 // implemented in "video.cc". This is done so that if an application
167 // doesn't need video support, it can just link with "null_video.cc"
168 // instead of "video.cc", which doesn't bring in the video-specific
169 // dependencies.
170
171 // Set in PeerConnectionFactory_initializeAndroidGlobals().
172 static bool factory_static_initialized = false;
173
NativeToJavaPeerConnectionFactory(JNIEnv * jni,rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,std::unique_ptr<rtc::Thread> network_thread,std::unique_ptr<rtc::Thread> worker_thread,std::unique_ptr<rtc::Thread> signaling_thread)174 jobject NativeToJavaPeerConnectionFactory(
175 JNIEnv* jni,
176 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pcf,
177 std::unique_ptr<rtc::Thread> network_thread,
178 std::unique_ptr<rtc::Thread> worker_thread,
179 std::unique_ptr<rtc::Thread> signaling_thread) {
180 return NativeToScopedJavaPeerConnectionFactory(
181 jni, pcf, std::move(network_thread), std::move(worker_thread),
182 std::move(signaling_thread))
183 .Release();
184 }
185
JNI_PeerConnectionFactory_InitializeAndroidGlobals(JNIEnv * jni)186 static void JNI_PeerConnectionFactory_InitializeAndroidGlobals(JNIEnv* jni) {
187 if (!factory_static_initialized) {
188 JVM::Initialize(GetJVM());
189 factory_static_initialized = true;
190 }
191 }
192
JNI_PeerConnectionFactory_InitializeFieldTrials(JNIEnv * jni,const JavaParamRef<jstring> & j_trials_init_string)193 static void JNI_PeerConnectionFactory_InitializeFieldTrials(
194 JNIEnv* jni,
195 const JavaParamRef<jstring>& j_trials_init_string) {
196 std::unique_ptr<std::string>& field_trials_init_string =
197 GetStaticObjects().field_trials_init_string;
198
199 if (j_trials_init_string.is_null()) {
200 field_trials_init_string = nullptr;
201 field_trial::InitFieldTrialsFromString(nullptr);
202 return;
203 }
204 field_trials_init_string = std::make_unique<std::string>(
205 JavaToNativeString(jni, j_trials_init_string));
206 RTC_LOG(LS_INFO) << "initializeFieldTrials: " << *field_trials_init_string;
207 field_trial::InitFieldTrialsFromString(field_trials_init_string->c_str());
208 }
209
JNI_PeerConnectionFactory_InitializeInternalTracer(JNIEnv * jni)210 static void JNI_PeerConnectionFactory_InitializeInternalTracer(JNIEnv* jni) {
211 rtc::tracing::SetupInternalTracer();
212 }
213
214 static ScopedJavaLocalRef<jstring>
JNI_PeerConnectionFactory_FindFieldTrialsFullName(JNIEnv * jni,const JavaParamRef<jstring> & j_name)215 JNI_PeerConnectionFactory_FindFieldTrialsFullName(
216 JNIEnv* jni,
217 const JavaParamRef<jstring>& j_name) {
218 return NativeToJavaString(
219 jni, field_trial::FindFullName(JavaToStdString(jni, j_name)));
220 }
221
JNI_PeerConnectionFactory_StartInternalTracingCapture(JNIEnv * jni,const JavaParamRef<jstring> & j_event_tracing_filename)222 static jboolean JNI_PeerConnectionFactory_StartInternalTracingCapture(
223 JNIEnv* jni,
224 const JavaParamRef<jstring>& j_event_tracing_filename) {
225 if (j_event_tracing_filename.is_null())
226 return false;
227
228 const char* init_string =
229 jni->GetStringUTFChars(j_event_tracing_filename.obj(), NULL);
230 RTC_LOG(LS_INFO) << "Starting internal tracing to: " << init_string;
231 bool ret = rtc::tracing::StartInternalCapture(init_string);
232 jni->ReleaseStringUTFChars(j_event_tracing_filename.obj(), init_string);
233 return ret;
234 }
235
JNI_PeerConnectionFactory_StopInternalTracingCapture(JNIEnv * jni)236 static void JNI_PeerConnectionFactory_StopInternalTracingCapture(JNIEnv* jni) {
237 rtc::tracing::StopInternalCapture();
238 }
239
JNI_PeerConnectionFactory_ShutdownInternalTracer(JNIEnv * jni)240 static void JNI_PeerConnectionFactory_ShutdownInternalTracer(JNIEnv* jni) {
241 rtc::tracing::ShutdownInternalTracer();
242 }
243
244 // Following parameters are optional:
245 // |audio_device_module|, |jencoder_factory|, |jdecoder_factory|,
246 // |audio_processor|, |fec_controller_factory|,
247 // |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)248 ScopedJavaLocalRef<jobject> CreatePeerConnectionFactoryForJava(
249 JNIEnv* jni,
250 const JavaParamRef<jobject>& jcontext,
251 const JavaParamRef<jobject>& joptions,
252 rtc::scoped_refptr<AudioDeviceModule> audio_device_module,
253 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
254 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
255 const JavaParamRef<jobject>& jencoder_factory,
256 const JavaParamRef<jobject>& jdecoder_factory,
257 rtc::scoped_refptr<AudioProcessing> audio_processor,
258 std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory,
259 std::unique_ptr<NetworkControllerFactoryInterface>
260 network_controller_factory,
261 std::unique_ptr<NetworkStatePredictorFactoryInterface>
262 network_state_predictor_factory,
263 std::unique_ptr<NetEqFactory> neteq_factory) {
264 // talk/ assumes pretty widely that the current Thread is ThreadManager'd, but
265 // ThreadManager only WrapCurrentThread()s the thread where it is first
266 // created. Since the semantics around when auto-wrapping happens in
267 // webrtc/rtc_base/ are convoluted, we simply wrap here to avoid having to
268 // think about ramifications of auto-wrapping there.
269 rtc::ThreadManager::Instance()->WrapCurrentThread();
270
271 std::unique_ptr<rtc::Thread> network_thread =
272 rtc::Thread::CreateWithSocketServer();
273 network_thread->SetName("network_thread", nullptr);
274 RTC_CHECK(network_thread->Start()) << "Failed to start thread";
275
276 std::unique_ptr<rtc::Thread> worker_thread = rtc::Thread::Create();
277 worker_thread->SetName("worker_thread", nullptr);
278 RTC_CHECK(worker_thread->Start()) << "Failed to start thread";
279
280 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
281 signaling_thread->SetName("signaling_thread", NULL);
282 RTC_CHECK(signaling_thread->Start()) << "Failed to start thread";
283
284 const absl::optional<PeerConnectionFactoryInterface::Options> options =
285 JavaToNativePeerConnectionFactoryOptions(jni, joptions);
286
287 PeerConnectionFactoryDependencies dependencies;
288 dependencies.network_thread = network_thread.get();
289 dependencies.worker_thread = worker_thread.get();
290 dependencies.signaling_thread = signaling_thread.get();
291 dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
292 dependencies.call_factory = CreateCallFactory();
293 dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>(
294 dependencies.task_queue_factory.get());
295 dependencies.fec_controller_factory = std::move(fec_controller_factory);
296 dependencies.network_controller_factory =
297 std::move(network_controller_factory);
298 dependencies.network_state_predictor_factory =
299 std::move(network_state_predictor_factory);
300 dependencies.neteq_factory = std::move(neteq_factory);
301 if (!(options && options->disable_network_monitor)) {
302 dependencies.network_monitor_factory =
303 std::make_unique<AndroidNetworkMonitorFactory>();
304 }
305
306 cricket::MediaEngineDependencies media_dependencies;
307 media_dependencies.task_queue_factory = dependencies.task_queue_factory.get();
308 media_dependencies.adm = std::move(audio_device_module);
309 media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory);
310 media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory);
311 media_dependencies.audio_processing = std::move(audio_processor);
312 media_dependencies.video_encoder_factory =
313 absl::WrapUnique(CreateVideoEncoderFactory(jni, jencoder_factory));
314 media_dependencies.video_decoder_factory =
315 absl::WrapUnique(CreateVideoDecoderFactory(jni, jdecoder_factory));
316 dependencies.media_engine =
317 cricket::CreateMediaEngine(std::move(media_dependencies));
318
319 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory =
320 CreateModularPeerConnectionFactory(std::move(dependencies));
321
322 RTC_CHECK(factory) << "Failed to create the peer connection factory; "
323 "WebRTC/libjingle init likely failed on this device";
324 // TODO(honghaiz): Maybe put the options as the argument of
325 // CreatePeerConnectionFactory.
326 if (options)
327 factory->SetOptions(*options);
328
329 return NativeToScopedJavaPeerConnectionFactory(
330 jni, factory, std::move(network_thread), std::move(worker_thread),
331 std::move(signaling_thread));
332 }
333
334 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)335 JNI_PeerConnectionFactory_CreatePeerConnectionFactory(
336 JNIEnv* jni,
337 const JavaParamRef<jobject>& jcontext,
338 const JavaParamRef<jobject>& joptions,
339 jlong native_audio_device_module,
340 jlong native_audio_encoder_factory,
341 jlong native_audio_decoder_factory,
342 const JavaParamRef<jobject>& jencoder_factory,
343 const JavaParamRef<jobject>& jdecoder_factory,
344 jlong native_audio_processor,
345 jlong native_fec_controller_factory,
346 jlong native_network_controller_factory,
347 jlong native_network_state_predictor_factory,
348 jlong native_neteq_factory) {
349 rtc::scoped_refptr<AudioProcessing> audio_processor =
350 reinterpret_cast<AudioProcessing*>(native_audio_processor);
351 return CreatePeerConnectionFactoryForJava(
352 jni, jcontext, joptions,
353 reinterpret_cast<AudioDeviceModule*>(native_audio_device_module),
354 TakeOwnershipOfRefPtr<AudioEncoderFactory>(native_audio_encoder_factory),
355 TakeOwnershipOfRefPtr<AudioDecoderFactory>(native_audio_decoder_factory),
356 jencoder_factory, jdecoder_factory,
357 audio_processor ? audio_processor : CreateAudioProcessing(),
358 TakeOwnershipOfUniquePtr<FecControllerFactoryInterface>(
359 native_fec_controller_factory),
360 TakeOwnershipOfUniquePtr<NetworkControllerFactoryInterface>(
361 native_network_controller_factory),
362 TakeOwnershipOfUniquePtr<NetworkStatePredictorFactoryInterface>(
363 native_network_state_predictor_factory),
364 TakeOwnershipOfUniquePtr<NetEqFactory>(native_neteq_factory));
365 }
366
JNI_PeerConnectionFactory_FreeFactory(JNIEnv *,jlong j_p)367 static void JNI_PeerConnectionFactory_FreeFactory(JNIEnv*,
368 jlong j_p) {
369 delete reinterpret_cast<OwnedFactoryAndThreads*>(j_p);
370 field_trial::InitFieldTrialsFromString(nullptr);
371 GetStaticObjects().field_trials_init_string = nullptr;
372 }
373
JNI_PeerConnectionFactory_CreateLocalMediaStream(JNIEnv * jni,jlong native_factory,const JavaParamRef<jstring> & label)374 static jlong JNI_PeerConnectionFactory_CreateLocalMediaStream(
375 JNIEnv* jni,
376 jlong native_factory,
377 const JavaParamRef<jstring>& label) {
378 rtc::scoped_refptr<MediaStreamInterface> stream(
379 PeerConnectionFactoryFromJava(native_factory)
380 ->CreateLocalMediaStream(JavaToStdString(jni, label)));
381 return jlongFromPointer(stream.release());
382 }
383
JNI_PeerConnectionFactory_CreateAudioSource(JNIEnv * jni,jlong native_factory,const JavaParamRef<jobject> & j_constraints)384 static jlong JNI_PeerConnectionFactory_CreateAudioSource(
385 JNIEnv* jni,
386 jlong native_factory,
387 const JavaParamRef<jobject>& j_constraints) {
388 std::unique_ptr<MediaConstraints> constraints =
389 JavaToNativeMediaConstraints(jni, j_constraints);
390 cricket::AudioOptions options;
391 CopyConstraintsIntoAudioOptions(constraints.get(), &options);
392 rtc::scoped_refptr<AudioSourceInterface> source(
393 PeerConnectionFactoryFromJava(native_factory)
394 ->CreateAudioSource(options));
395 return jlongFromPointer(source.release());
396 }
397
JNI_PeerConnectionFactory_CreateAudioTrack(JNIEnv * jni,jlong native_factory,const JavaParamRef<jstring> & id,jlong native_source)398 jlong JNI_PeerConnectionFactory_CreateAudioTrack(
399 JNIEnv* jni,
400 jlong native_factory,
401 const JavaParamRef<jstring>& id,
402 jlong native_source) {
403 rtc::scoped_refptr<AudioTrackInterface> track(
404 PeerConnectionFactoryFromJava(native_factory)
405 ->CreateAudioTrack(
406 JavaToStdString(jni, id),
407 reinterpret_cast<AudioSourceInterface*>(native_source)));
408 return jlongFromPointer(track.release());
409 }
410
JNI_PeerConnectionFactory_StartAecDump(JNIEnv * jni,jlong native_factory,jint file_descriptor,jint filesize_limit_bytes)411 static jboolean JNI_PeerConnectionFactory_StartAecDump(
412 JNIEnv* jni,
413 jlong native_factory,
414 jint file_descriptor,
415 jint filesize_limit_bytes) {
416 FILE* f = fdopen(file_descriptor, "wb");
417 if (!f) {
418 close(file_descriptor);
419 return false;
420 }
421
422 return PeerConnectionFactoryFromJava(native_factory)
423 ->StartAecDump(f, filesize_limit_bytes);
424 }
425
JNI_PeerConnectionFactory_StopAecDump(JNIEnv * jni,jlong native_factory)426 static void JNI_PeerConnectionFactory_StopAecDump(JNIEnv* jni,
427 jlong native_factory) {
428 PeerConnectionFactoryFromJava(native_factory)->StopAecDump();
429 }
430
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)431 static jlong JNI_PeerConnectionFactory_CreatePeerConnection(
432 JNIEnv* jni,
433 jlong factory,
434 const JavaParamRef<jobject>& j_rtc_config,
435 const JavaParamRef<jobject>& j_constraints,
436 jlong observer_p,
437 const JavaParamRef<jobject>& j_sslCertificateVerifier) {
438 std::unique_ptr<PeerConnectionObserver> observer(
439 reinterpret_cast<PeerConnectionObserver*>(observer_p));
440
441 PeerConnectionInterface::RTCConfiguration rtc_config(
442 PeerConnectionInterface::RTCConfigurationType::kAggressive);
443 JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
444
445 if (rtc_config.certificates.empty()) {
446 // Generate non-default certificate.
447 rtc::KeyType key_type = GetRtcConfigKeyType(jni, j_rtc_config);
448 if (key_type != rtc::KT_DEFAULT) {
449 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
450 rtc::RTCCertificateGenerator::GenerateCertificate(
451 rtc::KeyParams(key_type), absl::nullopt);
452 if (!certificate) {
453 RTC_LOG(LS_ERROR) << "Failed to generate certificate. KeyType: "
454 << key_type;
455 return 0;
456 }
457 rtc_config.certificates.push_back(certificate);
458 }
459 }
460
461 std::unique_ptr<MediaConstraints> constraints;
462 if (!j_constraints.is_null()) {
463 constraints = JavaToNativeMediaConstraints(jni, j_constraints);
464 CopyConstraintsIntoRtcConfiguration(constraints.get(), &rtc_config);
465 }
466
467 PeerConnectionDependencies peer_connection_dependencies(observer.get());
468 if (!j_sslCertificateVerifier.is_null()) {
469 peer_connection_dependencies.tls_cert_verifier =
470 std::make_unique<SSLCertificateVerifierWrapper>(
471 jni, j_sslCertificateVerifier);
472 }
473
474 rtc::scoped_refptr<PeerConnectionInterface> pc =
475 PeerConnectionFactoryFromJava(factory)->CreatePeerConnection(
476 rtc_config, std::move(peer_connection_dependencies));
477 if (!pc)
478 return 0;
479
480 return jlongFromPointer(
481 new OwnedPeerConnection(pc, std::move(observer), std::move(constraints)));
482 }
483
JNI_PeerConnectionFactory_CreateVideoSource(JNIEnv * jni,jlong native_factory,jboolean is_screencast,jboolean align_timestamps)484 static jlong JNI_PeerConnectionFactory_CreateVideoSource(
485 JNIEnv* jni,
486 jlong native_factory,
487 jboolean is_screencast,
488 jboolean align_timestamps) {
489 OwnedFactoryAndThreads* factory =
490 reinterpret_cast<OwnedFactoryAndThreads*>(native_factory);
491 return jlongFromPointer(CreateVideoSource(jni, factory->signaling_thread(),
492 factory->worker_thread(),
493 is_screencast, align_timestamps));
494 }
495
JNI_PeerConnectionFactory_CreateVideoTrack(JNIEnv * jni,jlong native_factory,const JavaParamRef<jstring> & id,jlong native_source)496 static jlong JNI_PeerConnectionFactory_CreateVideoTrack(
497 JNIEnv* jni,
498 jlong native_factory,
499 const JavaParamRef<jstring>& id,
500 jlong native_source) {
501 rtc::scoped_refptr<VideoTrackInterface> track =
502 PeerConnectionFactoryFromJava(native_factory)
503 ->CreateVideoTrack(
504 JavaToStdString(jni, id),
505 reinterpret_cast<VideoTrackSourceInterface*>(native_source));
506 return jlongFromPointer(track.release());
507 }
508
JNI_PeerConnectionFactory_GetNativePeerConnectionFactory(JNIEnv * jni,jlong native_factory)509 static jlong JNI_PeerConnectionFactory_GetNativePeerConnectionFactory(
510 JNIEnv* jni,
511 jlong native_factory) {
512 return jlongFromPointer(PeerConnectionFactoryFromJava(native_factory));
513 }
514
JNI_PeerConnectionFactory_InjectLoggable(JNIEnv * jni,const JavaParamRef<jobject> & j_logging,jint nativeSeverity)515 static void JNI_PeerConnectionFactory_InjectLoggable(
516 JNIEnv* jni,
517 const JavaParamRef<jobject>& j_logging,
518 jint nativeSeverity) {
519 std::unique_ptr<JNILogSink>& jni_log_sink = GetStaticObjects().jni_log_sink;
520
521 // If there is already a LogSink, remove it from LogMessage.
522 if (jni_log_sink) {
523 rtc::LogMessage::RemoveLogToStream(jni_log_sink.get());
524 }
525 jni_log_sink = std::make_unique<JNILogSink>(jni, j_logging);
526 rtc::LogMessage::AddLogToStream(
527 jni_log_sink.get(), static_cast<rtc::LoggingSeverity>(nativeSeverity));
528 rtc::LogMessage::LogToDebug(rtc::LS_NONE);
529 }
530
JNI_PeerConnectionFactory_DeleteLoggable(JNIEnv * jni)531 static void JNI_PeerConnectionFactory_DeleteLoggable(JNIEnv* jni) {
532 std::unique_ptr<JNILogSink>& jni_log_sink = GetStaticObjects().jni_log_sink;
533
534 if (jni_log_sink) {
535 rtc::LogMessage::RemoveLogToStream(jni_log_sink.get());
536 jni_log_sink.reset();
537 }
538 }
539
JNI_PeerConnectionFactory_PrintStackTrace(JNIEnv * env,jint tid)540 static void JNI_PeerConnectionFactory_PrintStackTrace(JNIEnv* env, jint tid) {
541 RTC_LOG(LS_WARNING) << StackTraceToString(GetStackTrace(tid));
542 }
543
JNI_PeerConnectionFactory_PrintStackTracesOfRegisteredThreads(JNIEnv * env)544 static void JNI_PeerConnectionFactory_PrintStackTracesOfRegisteredThreads(
545 JNIEnv* env) {
546 PrintStackTracesOfRegisteredThreads();
547 }
548
549 } // namespace jni
550 } // namespace webrtc
551