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