xref: /aosp_15_r20/external/webrtc/sdk/android/src/jni/pc/peer_connection_factory.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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