• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2013 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 // Lifecycle notes: objects are owned where they will be called; in other words
12 // FooObservers are owned by C++-land, and user-callable objects (e.g.
13 // PeerConnection and VideoTrack) are owned by Java-land.
14 // When this file (or other files in this directory) allocates C++
15 // RefCountInterfaces it AddRef()s an artificial ref simulating the jlong held
16 // in Java-land, and then Release()s the ref in the respective free call.
17 // Sometimes this AddRef is implicit in the construction of a scoped_refptr<>
18 // which is then .release()d. Any persistent (non-local) references from C++ to
19 // Java must be global or weak (in which case they must be checked before use)!
20 //
21 // Exception notes: pretty much all JNI calls can throw Java exceptions, so each
22 // call through a JNIEnv* pointer needs to be followed by an ExceptionCheck()
23 // call. In this file this is done in CHECK_EXCEPTION, making for much easier
24 // debugging in case of failure (the alternative is to wait for control to
25 // return to the Java frame that called code in this file, at which point it's
26 // impossible to tell which JNI call broke).
27 
28 #include "sdk/android/src/jni/pc/peer_connection.h"
29 
30 #include <limits>
31 #include <memory>
32 #include <string>
33 #include <utility>
34 
35 #include "api/peer_connection_interface.h"
36 #include "api/rtc_event_log_output_file.h"
37 #include "api/rtp_receiver_interface.h"
38 #include "api/rtp_sender_interface.h"
39 #include "api/rtp_transceiver_interface.h"
40 #include "rtc_base/checks.h"
41 #include "rtc_base/logging.h"
42 #include "rtc_base/numerics/safe_conversions.h"
43 #include "sdk/android/generated_peerconnection_jni/CandidatePairChangeEvent_jni.h"
44 #include "sdk/android/generated_peerconnection_jni/IceCandidateErrorEvent_jni.h"
45 #include "sdk/android/generated_peerconnection_jni/PeerConnection_jni.h"
46 #include "sdk/android/native_api/jni/java_types.h"
47 #include "sdk/android/src/jni/jni_helpers.h"
48 #include "sdk/android/src/jni/pc/add_ice_candidate_observer.h"
49 #include "sdk/android/src/jni/pc/crypto_options.h"
50 #include "sdk/android/src/jni/pc/data_channel.h"
51 #include "sdk/android/src/jni/pc/ice_candidate.h"
52 #include "sdk/android/src/jni/pc/media_constraints.h"
53 #include "sdk/android/src/jni/pc/media_stream_track.h"
54 #include "sdk/android/src/jni/pc/rtc_certificate.h"
55 #include "sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.h"
56 #include "sdk/android/src/jni/pc/rtp_sender.h"
57 #include "sdk/android/src/jni/pc/sdp_observer.h"
58 #include "sdk/android/src/jni/pc/session_description.h"
59 #include "sdk/android/src/jni/pc/stats_observer.h"
60 #include "sdk/android/src/jni/pc/turn_customizer.h"
61 
62 namespace webrtc {
63 namespace jni {
64 
65 namespace {
66 
ExtractNativePC(JNIEnv * jni,const JavaRef<jobject> & j_pc)67 PeerConnectionInterface* ExtractNativePC(JNIEnv* jni,
68                                          const JavaRef<jobject>& j_pc) {
69   return reinterpret_cast<OwnedPeerConnection*>(
70              Java_PeerConnection_getNativeOwnedPeerConnection(jni, j_pc))
71       ->pc();
72 }
73 
JavaToNativeIceServers(JNIEnv * jni,const JavaRef<jobject> & j_ice_servers)74 PeerConnectionInterface::IceServers JavaToNativeIceServers(
75     JNIEnv* jni,
76     const JavaRef<jobject>& j_ice_servers) {
77   PeerConnectionInterface::IceServers ice_servers;
78   for (const JavaRef<jobject>& j_ice_server : Iterable(jni, j_ice_servers)) {
79     ScopedJavaLocalRef<jobject> j_ice_server_tls_cert_policy =
80         Java_IceServer_getTlsCertPolicy(jni, j_ice_server);
81     ScopedJavaLocalRef<jobject> urls =
82         Java_IceServer_getUrls(jni, j_ice_server);
83     ScopedJavaLocalRef<jstring> username =
84         Java_IceServer_getUsername(jni, j_ice_server);
85     ScopedJavaLocalRef<jstring> password =
86         Java_IceServer_getPassword(jni, j_ice_server);
87     PeerConnectionInterface::TlsCertPolicy tls_cert_policy =
88         JavaToNativeTlsCertPolicy(jni, j_ice_server_tls_cert_policy);
89     ScopedJavaLocalRef<jstring> hostname =
90         Java_IceServer_getHostname(jni, j_ice_server);
91     ScopedJavaLocalRef<jobject> tls_alpn_protocols =
92         Java_IceServer_getTlsAlpnProtocols(jni, j_ice_server);
93     ScopedJavaLocalRef<jobject> tls_elliptic_curves =
94         Java_IceServer_getTlsEllipticCurves(jni, j_ice_server);
95     PeerConnectionInterface::IceServer server;
96     server.urls = JavaListToNativeVector<std::string, jstring>(
97         jni, urls, &JavaToNativeString);
98     server.username = JavaToNativeString(jni, username);
99     server.password = JavaToNativeString(jni, password);
100     server.tls_cert_policy = tls_cert_policy;
101     server.hostname = JavaToNativeString(jni, hostname);
102     server.tls_alpn_protocols = JavaListToNativeVector<std::string, jstring>(
103         jni, tls_alpn_protocols, &JavaToNativeString);
104     server.tls_elliptic_curves = JavaListToNativeVector<std::string, jstring>(
105         jni, tls_elliptic_curves, &JavaToNativeString);
106     ice_servers.push_back(server);
107   }
108   return ice_servers;
109 }
110 
JavaToNativeSdpSemantics(JNIEnv * jni,const JavaRef<jobject> & j_sdp_semantics)111 SdpSemantics JavaToNativeSdpSemantics(JNIEnv* jni,
112                                       const JavaRef<jobject>& j_sdp_semantics) {
113   std::string enum_name = GetJavaEnumName(jni, j_sdp_semantics);
114 
115   if (enum_name == "PLAN_B")
116     return SdpSemantics::kPlanB_DEPRECATED;
117 
118   if (enum_name == "UNIFIED_PLAN")
119     return SdpSemantics::kUnifiedPlan;
120 
121   RTC_DCHECK_NOTREACHED();
122   return SdpSemantics::kUnifiedPlan;
123 }
124 
NativeToJavaCandidatePairChange(JNIEnv * env,const cricket::CandidatePairChangeEvent & event)125 ScopedJavaLocalRef<jobject> NativeToJavaCandidatePairChange(
126     JNIEnv* env,
127     const cricket::CandidatePairChangeEvent& event) {
128   const auto& selected_pair = event.selected_candidate_pair;
129   return Java_CandidatePairChangeEvent_Constructor(
130       env, NativeToJavaCandidate(env, selected_pair.local_candidate()),
131       NativeToJavaCandidate(env, selected_pair.remote_candidate()),
132       static_cast<int>(event.last_data_received_ms),
133       NativeToJavaString(env, event.reason),
134       static_cast<int>(event.estimated_disconnected_time_ms));
135 }
136 
137 }  // namespace
138 
NativeToJavaAdapterType(JNIEnv * env,int adapterType)139 ScopedJavaLocalRef<jobject> NativeToJavaAdapterType(JNIEnv* env,
140                                                     int adapterType) {
141   return Java_AdapterType_fromNativeIndex(env, adapterType);
142 }
143 
JavaToNativeRTCConfiguration(JNIEnv * jni,const JavaRef<jobject> & j_rtc_config,PeerConnectionInterface::RTCConfiguration * rtc_config)144 void JavaToNativeRTCConfiguration(
145     JNIEnv* jni,
146     const JavaRef<jobject>& j_rtc_config,
147     PeerConnectionInterface::RTCConfiguration* rtc_config) {
148   ScopedJavaLocalRef<jobject> j_ice_transports_type =
149       Java_RTCConfiguration_getIceTransportsType(jni, j_rtc_config);
150   ScopedJavaLocalRef<jobject> j_bundle_policy =
151       Java_RTCConfiguration_getBundlePolicy(jni, j_rtc_config);
152   ScopedJavaLocalRef<jobject> j_rtcp_mux_policy =
153       Java_RTCConfiguration_getRtcpMuxPolicy(jni, j_rtc_config);
154   ScopedJavaLocalRef<jobject> j_rtc_certificate =
155       Java_RTCConfiguration_getCertificate(jni, j_rtc_config);
156   ScopedJavaLocalRef<jobject> j_tcp_candidate_policy =
157       Java_RTCConfiguration_getTcpCandidatePolicy(jni, j_rtc_config);
158   ScopedJavaLocalRef<jobject> j_candidate_network_policy =
159       Java_RTCConfiguration_getCandidateNetworkPolicy(jni, j_rtc_config);
160   ScopedJavaLocalRef<jobject> j_ice_servers =
161       Java_RTCConfiguration_getIceServers(jni, j_rtc_config);
162   ScopedJavaLocalRef<jobject> j_continual_gathering_policy =
163       Java_RTCConfiguration_getContinualGatheringPolicy(jni, j_rtc_config);
164   ScopedJavaLocalRef<jobject> j_turn_port_prune_policy =
165       Java_RTCConfiguration_getTurnPortPrunePolicy(jni, j_rtc_config);
166   ScopedJavaLocalRef<jobject> j_turn_customizer =
167       Java_RTCConfiguration_getTurnCustomizer(jni, j_rtc_config);
168   ScopedJavaLocalRef<jobject> j_network_preference =
169       Java_RTCConfiguration_getNetworkPreference(jni, j_rtc_config);
170   ScopedJavaLocalRef<jobject> j_sdp_semantics =
171       Java_RTCConfiguration_getSdpSemantics(jni, j_rtc_config);
172   ScopedJavaLocalRef<jobject> j_crypto_options =
173       Java_RTCConfiguration_getCryptoOptions(jni, j_rtc_config);
174 
175   rtc_config->type = JavaToNativeIceTransportsType(jni, j_ice_transports_type);
176   rtc_config->bundle_policy = JavaToNativeBundlePolicy(jni, j_bundle_policy);
177   rtc_config->rtcp_mux_policy =
178       JavaToNativeRtcpMuxPolicy(jni, j_rtcp_mux_policy);
179   if (!j_rtc_certificate.is_null()) {
180     rtc::scoped_refptr<rtc::RTCCertificate> certificate =
181         rtc::RTCCertificate::FromPEM(
182             JavaToNativeRTCCertificatePEM(jni, j_rtc_certificate));
183     RTC_CHECK(certificate != nullptr) << "supplied certificate is malformed.";
184     rtc_config->certificates.push_back(certificate);
185   }
186   rtc_config->tcp_candidate_policy =
187       JavaToNativeTcpCandidatePolicy(jni, j_tcp_candidate_policy);
188   rtc_config->candidate_network_policy =
189       JavaToNativeCandidateNetworkPolicy(jni, j_candidate_network_policy);
190   rtc_config->servers = JavaToNativeIceServers(jni, j_ice_servers);
191   rtc_config->audio_jitter_buffer_max_packets =
192       Java_RTCConfiguration_getAudioJitterBufferMaxPackets(jni, j_rtc_config);
193   rtc_config->audio_jitter_buffer_fast_accelerate =
194       Java_RTCConfiguration_getAudioJitterBufferFastAccelerate(jni,
195                                                                j_rtc_config);
196   rtc_config->ice_connection_receiving_timeout =
197       Java_RTCConfiguration_getIceConnectionReceivingTimeout(jni, j_rtc_config);
198   rtc_config->ice_backup_candidate_pair_ping_interval =
199       Java_RTCConfiguration_getIceBackupCandidatePairPingInterval(jni,
200                                                                   j_rtc_config);
201   rtc_config->continual_gathering_policy =
202       JavaToNativeContinualGatheringPolicy(jni, j_continual_gathering_policy);
203   rtc_config->ice_candidate_pool_size =
204       Java_RTCConfiguration_getIceCandidatePoolSize(jni, j_rtc_config);
205   rtc_config->prune_turn_ports =
206       Java_RTCConfiguration_getPruneTurnPorts(jni, j_rtc_config);
207   rtc_config->turn_port_prune_policy =
208       JavaToNativePortPrunePolicy(jni, j_turn_port_prune_policy);
209   rtc_config->presume_writable_when_fully_relayed =
210       Java_RTCConfiguration_getPresumeWritableWhenFullyRelayed(jni,
211                                                                j_rtc_config);
212   rtc_config->surface_ice_candidates_on_ice_transport_type_changed =
213       Java_RTCConfiguration_getSurfaceIceCandidatesOnIceTransportTypeChanged(
214           jni, j_rtc_config);
215   ScopedJavaLocalRef<jobject> j_ice_check_interval_strong_connectivity =
216       Java_RTCConfiguration_getIceCheckIntervalStrongConnectivity(jni,
217                                                                   j_rtc_config);
218   rtc_config->ice_check_interval_strong_connectivity =
219       JavaToNativeOptionalInt(jni, j_ice_check_interval_strong_connectivity);
220   ScopedJavaLocalRef<jobject> j_ice_check_interval_weak_connectivity =
221       Java_RTCConfiguration_getIceCheckIntervalWeakConnectivity(jni,
222                                                                 j_rtc_config);
223   rtc_config->ice_check_interval_weak_connectivity =
224       JavaToNativeOptionalInt(jni, j_ice_check_interval_weak_connectivity);
225   ScopedJavaLocalRef<jobject> j_ice_check_min_interval =
226       Java_RTCConfiguration_getIceCheckMinInterval(jni, j_rtc_config);
227   rtc_config->ice_check_min_interval =
228       JavaToNativeOptionalInt(jni, j_ice_check_min_interval);
229   ScopedJavaLocalRef<jobject> j_ice_unwritable_timeout =
230       Java_RTCConfiguration_getIceUnwritableTimeout(jni, j_rtc_config);
231   rtc_config->ice_unwritable_timeout =
232       JavaToNativeOptionalInt(jni, j_ice_unwritable_timeout);
233   ScopedJavaLocalRef<jobject> j_ice_unwritable_min_checks =
234       Java_RTCConfiguration_getIceUnwritableMinChecks(jni, j_rtc_config);
235   rtc_config->ice_unwritable_min_checks =
236       JavaToNativeOptionalInt(jni, j_ice_unwritable_min_checks);
237   ScopedJavaLocalRef<jobject> j_stun_candidate_keepalive_interval =
238       Java_RTCConfiguration_getStunCandidateKeepaliveInterval(jni,
239                                                               j_rtc_config);
240   rtc_config->stun_candidate_keepalive_interval =
241       JavaToNativeOptionalInt(jni, j_stun_candidate_keepalive_interval);
242   ScopedJavaLocalRef<jobject> j_stable_writable_connection_ping_interval_ms =
243       Java_RTCConfiguration_getStableWritableConnectionPingIntervalMs(
244           jni, j_rtc_config);
245   rtc_config->stable_writable_connection_ping_interval_ms =
246       JavaToNativeOptionalInt(jni,
247                               j_stable_writable_connection_ping_interval_ms);
248   rtc_config->disable_ipv6_on_wifi =
249       Java_RTCConfiguration_getDisableIPv6OnWifi(jni, j_rtc_config);
250   rtc_config->max_ipv6_networks =
251       Java_RTCConfiguration_getMaxIPv6Networks(jni, j_rtc_config);
252 
253   rtc_config->turn_customizer = GetNativeTurnCustomizer(jni, j_turn_customizer);
254 
255   rtc_config->media_config.enable_dscp =
256       Java_RTCConfiguration_getEnableDscp(jni, j_rtc_config);
257   rtc_config->media_config.video.enable_cpu_adaptation =
258       Java_RTCConfiguration_getEnableCpuOveruseDetection(jni, j_rtc_config);
259   rtc_config->media_config.video.suspend_below_min_bitrate =
260       Java_RTCConfiguration_getSuspendBelowMinBitrate(jni, j_rtc_config);
261   rtc_config->screencast_min_bitrate = JavaToNativeOptionalInt(
262       jni, Java_RTCConfiguration_getScreencastMinBitrate(jni, j_rtc_config));
263   rtc_config->combined_audio_video_bwe = JavaToNativeOptionalBool(
264       jni, Java_RTCConfiguration_getCombinedAudioVideoBwe(jni, j_rtc_config));
265   rtc_config->network_preference =
266       JavaToNativeNetworkPreference(jni, j_network_preference);
267   rtc_config->sdp_semantics = JavaToNativeSdpSemantics(jni, j_sdp_semantics);
268   rtc_config->active_reset_srtp_params =
269       Java_RTCConfiguration_getActiveResetSrtpParams(jni, j_rtc_config);
270   rtc_config->crypto_options =
271       JavaToNativeOptionalCryptoOptions(jni, j_crypto_options);
272 
273   rtc_config->allow_codec_switching = JavaToNativeOptionalBool(
274       jni, Java_RTCConfiguration_getAllowCodecSwitching(jni, j_rtc_config));
275 
276   rtc_config->offer_extmap_allow_mixed =
277       Java_RTCConfiguration_getOfferExtmapAllowMixed(jni, j_rtc_config);
278   rtc_config->enable_implicit_rollback =
279       Java_RTCConfiguration_getEnableImplicitRollback(jni, j_rtc_config);
280 
281   ScopedJavaLocalRef<jstring> j_turn_logging_id =
282       Java_RTCConfiguration_getTurnLoggingId(jni, j_rtc_config);
283   if (!IsNull(jni, j_turn_logging_id)) {
284     rtc_config->turn_logging_id = JavaToNativeString(jni, j_turn_logging_id);
285   }
286 }
287 
GetRtcConfigKeyType(JNIEnv * env,const JavaRef<jobject> & j_rtc_config)288 rtc::KeyType GetRtcConfigKeyType(JNIEnv* env,
289                                  const JavaRef<jobject>& j_rtc_config) {
290   return JavaToNativeKeyType(
291       env, Java_RTCConfiguration_getKeyType(env, j_rtc_config));
292 }
293 
PeerConnectionObserverJni(JNIEnv * jni,const JavaRef<jobject> & j_observer)294 PeerConnectionObserverJni::PeerConnectionObserverJni(
295     JNIEnv* jni,
296     const JavaRef<jobject>& j_observer)
297     : j_observer_global_(jni, j_observer) {}
298 
299 PeerConnectionObserverJni::~PeerConnectionObserverJni() = default;
300 
OnIceCandidate(const IceCandidateInterface * candidate)301 void PeerConnectionObserverJni::OnIceCandidate(
302     const IceCandidateInterface* candidate) {
303   JNIEnv* env = AttachCurrentThreadIfNeeded();
304   Java_Observer_onIceCandidate(env, j_observer_global_,
305                                NativeToJavaIceCandidate(env, *candidate));
306 }
307 
OnIceCandidateError(const std::string & address,int port,const std::string & url,int error_code,const std::string & error_text)308 void PeerConnectionObserverJni::OnIceCandidateError(
309     const std::string& address,
310     int port,
311     const std::string& url,
312     int error_code,
313     const std::string& error_text) {
314   JNIEnv* env = AttachCurrentThreadIfNeeded();
315   ScopedJavaLocalRef<jobject> event = Java_IceCandidateErrorEvent_Constructor(
316       env, NativeToJavaString(env, address), port, NativeToJavaString(env, url),
317       error_code, NativeToJavaString(env, error_text));
318   Java_Observer_onIceCandidateError(env, j_observer_global_, event);
319 }
320 
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)321 void PeerConnectionObserverJni::OnIceCandidatesRemoved(
322     const std::vector<cricket::Candidate>& candidates) {
323   JNIEnv* env = AttachCurrentThreadIfNeeded();
324   Java_Observer_onIceCandidatesRemoved(
325       env, j_observer_global_, NativeToJavaCandidateArray(env, candidates));
326 }
327 
OnSignalingChange(PeerConnectionInterface::SignalingState new_state)328 void PeerConnectionObserverJni::OnSignalingChange(
329     PeerConnectionInterface::SignalingState new_state) {
330   JNIEnv* env = AttachCurrentThreadIfNeeded();
331   Java_Observer_onSignalingChange(
332       env, j_observer_global_,
333       Java_SignalingState_fromNativeIndex(env, new_state));
334 }
335 
OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)336 void PeerConnectionObserverJni::OnIceConnectionChange(
337     PeerConnectionInterface::IceConnectionState new_state) {
338   JNIEnv* env = AttachCurrentThreadIfNeeded();
339   Java_Observer_onIceConnectionChange(
340       env, j_observer_global_,
341       Java_IceConnectionState_fromNativeIndex(env, new_state));
342 }
343 
OnStandardizedIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)344 void PeerConnectionObserverJni::OnStandardizedIceConnectionChange(
345     PeerConnectionInterface::IceConnectionState new_state) {
346   JNIEnv* env = AttachCurrentThreadIfNeeded();
347   Java_Observer_onStandardizedIceConnectionChange(
348       env, j_observer_global_,
349       Java_IceConnectionState_fromNativeIndex(env, new_state));
350 }
351 
OnConnectionChange(PeerConnectionInterface::PeerConnectionState new_state)352 void PeerConnectionObserverJni::OnConnectionChange(
353     PeerConnectionInterface::PeerConnectionState new_state) {
354   JNIEnv* env = AttachCurrentThreadIfNeeded();
355   Java_Observer_onConnectionChange(env, j_observer_global_,
356                                    Java_PeerConnectionState_fromNativeIndex(
357                                        env, static_cast<int>(new_state)));
358 }
359 
OnIceConnectionReceivingChange(bool receiving)360 void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) {
361   JNIEnv* env = AttachCurrentThreadIfNeeded();
362   Java_Observer_onIceConnectionReceivingChange(env, j_observer_global_,
363                                                receiving);
364 }
365 
OnIceSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent & event)366 void PeerConnectionObserverJni::OnIceSelectedCandidatePairChanged(
367     const cricket::CandidatePairChangeEvent& event) {
368   JNIEnv* env = AttachCurrentThreadIfNeeded();
369   Java_Observer_onSelectedCandidatePairChanged(
370       env, j_observer_global_, NativeToJavaCandidatePairChange(env, event));
371 }
372 
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)373 void PeerConnectionObserverJni::OnIceGatheringChange(
374     PeerConnectionInterface::IceGatheringState new_state) {
375   JNIEnv* env = AttachCurrentThreadIfNeeded();
376   Java_Observer_onIceGatheringChange(
377       env, j_observer_global_,
378       Java_IceGatheringState_fromNativeIndex(env, new_state));
379 }
380 
OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream)381 void PeerConnectionObserverJni::OnAddStream(
382     rtc::scoped_refptr<MediaStreamInterface> stream) {
383   JNIEnv* env = AttachCurrentThreadIfNeeded();
384   Java_Observer_onAddStream(
385       env, j_observer_global_,
386       GetOrCreateJavaStream(env, stream).j_media_stream());
387 }
388 
OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream)389 void PeerConnectionObserverJni::OnRemoveStream(
390     rtc::scoped_refptr<MediaStreamInterface> stream) {
391   JNIEnv* env = AttachCurrentThreadIfNeeded();
392   NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream.get());
393   RTC_CHECK(it != remote_streams_.end())
394       << "unexpected stream: " << stream.get();
395   Java_Observer_onRemoveStream(env, j_observer_global_,
396                                it->second.j_media_stream());
397   remote_streams_.erase(it);
398 }
399 
OnDataChannel(rtc::scoped_refptr<DataChannelInterface> channel)400 void PeerConnectionObserverJni::OnDataChannel(
401     rtc::scoped_refptr<DataChannelInterface> channel) {
402   JNIEnv* env = AttachCurrentThreadIfNeeded();
403   Java_Observer_onDataChannel(env, j_observer_global_,
404                               WrapNativeDataChannel(env, channel));
405 }
406 
OnRenegotiationNeeded()407 void PeerConnectionObserverJni::OnRenegotiationNeeded() {
408   JNIEnv* env = AttachCurrentThreadIfNeeded();
409   Java_Observer_onRenegotiationNeeded(env, j_observer_global_);
410 }
411 
OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)412 void PeerConnectionObserverJni::OnAddTrack(
413     rtc::scoped_refptr<RtpReceiverInterface> receiver,
414     const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
415   JNIEnv* env = AttachCurrentThreadIfNeeded();
416   ScopedJavaLocalRef<jobject> j_rtp_receiver =
417       NativeToJavaRtpReceiver(env, receiver);
418   rtp_receivers_.emplace_back(env, j_rtp_receiver);
419 
420   Java_Observer_onAddTrack(env, j_observer_global_, j_rtp_receiver,
421                            NativeToJavaMediaStreamArray(env, streams));
422 }
423 
OnRemoveTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver)424 void PeerConnectionObserverJni::OnRemoveTrack(
425     rtc::scoped_refptr<RtpReceiverInterface> receiver) {
426   JNIEnv* env = AttachCurrentThreadIfNeeded();
427   ScopedJavaLocalRef<jobject> j_rtp_receiver =
428       NativeToJavaRtpReceiver(env, receiver);
429   rtp_receivers_.emplace_back(env, j_rtp_receiver);
430 
431   Java_Observer_onRemoveTrack(env, j_observer_global_, j_rtp_receiver);
432 }
433 
OnTrack(rtc::scoped_refptr<RtpTransceiverInterface> transceiver)434 void PeerConnectionObserverJni::OnTrack(
435     rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
436   JNIEnv* env = AttachCurrentThreadIfNeeded();
437   ScopedJavaLocalRef<jobject> j_rtp_transceiver =
438       NativeToJavaRtpTransceiver(env, transceiver);
439   rtp_transceivers_.emplace_back(env, j_rtp_transceiver);
440 
441   Java_Observer_onTrack(env, j_observer_global_, j_rtp_transceiver);
442 }
443 
444 // If the NativeToJavaStreamsMap contains the stream, return it.
445 // Otherwise, create a new Java MediaStream.
GetOrCreateJavaStream(JNIEnv * env,const rtc::scoped_refptr<MediaStreamInterface> & stream)446 JavaMediaStream& PeerConnectionObserverJni::GetOrCreateJavaStream(
447     JNIEnv* env,
448     const rtc::scoped_refptr<MediaStreamInterface>& stream) {
449   NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream.get());
450   if (it == remote_streams_.end()) {
451     it = remote_streams_
452              .emplace(std::piecewise_construct,
453                       std::forward_as_tuple(stream.get()),
454                       std::forward_as_tuple(env, stream))
455              .first;
456   }
457   return it->second;
458 }
459 
460 ScopedJavaLocalRef<jobjectArray>
NativeToJavaMediaStreamArray(JNIEnv * jni,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)461 PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
462     JNIEnv* jni,
463     const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
464   return NativeToJavaObjectArray(
465       jni, streams, GetMediaStreamClass(jni),
466       [this](JNIEnv* env, rtc::scoped_refptr<MediaStreamInterface> stream)
467           -> const ScopedJavaGlobalRef<jobject>& {
468         return GetOrCreateJavaStream(env, stream).j_media_stream();
469       });
470 }
471 
OwnedPeerConnection(rtc::scoped_refptr<PeerConnectionInterface> peer_connection,std::unique_ptr<PeerConnectionObserver> observer)472 OwnedPeerConnection::OwnedPeerConnection(
473     rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
474     std::unique_ptr<PeerConnectionObserver> observer)
475     : OwnedPeerConnection(peer_connection,
476                           std::move(observer),
477                           nullptr /* constraints */) {}
478 
OwnedPeerConnection(rtc::scoped_refptr<PeerConnectionInterface> peer_connection,std::unique_ptr<PeerConnectionObserver> observer,std::unique_ptr<MediaConstraints> constraints)479 OwnedPeerConnection::OwnedPeerConnection(
480     rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
481     std::unique_ptr<PeerConnectionObserver> observer,
482     std::unique_ptr<MediaConstraints> constraints)
483     : peer_connection_(peer_connection),
484       observer_(std::move(observer)),
485       constraints_(std::move(constraints)) {}
486 
~OwnedPeerConnection()487 OwnedPeerConnection::~OwnedPeerConnection() {
488   // Ensure that PeerConnection is destroyed before the observer.
489   peer_connection_ = nullptr;
490 }
491 
JNI_PeerConnection_CreatePeerConnectionObserver(JNIEnv * jni,const JavaParamRef<jobject> & j_observer)492 static jlong JNI_PeerConnection_CreatePeerConnectionObserver(
493     JNIEnv* jni,
494     const JavaParamRef<jobject>& j_observer) {
495   return jlongFromPointer(new PeerConnectionObserverJni(jni, j_observer));
496 }
497 
JNI_PeerConnection_FreeOwnedPeerConnection(JNIEnv *,jlong j_p)498 static void JNI_PeerConnection_FreeOwnedPeerConnection(JNIEnv*, jlong j_p) {
499   delete reinterpret_cast<OwnedPeerConnection*>(j_p);
500 }
501 
JNI_PeerConnection_GetNativePeerConnection(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)502 static jlong JNI_PeerConnection_GetNativePeerConnection(
503     JNIEnv* jni,
504     const JavaParamRef<jobject>& j_pc) {
505   return jlongFromPointer(ExtractNativePC(jni, j_pc));
506 }
507 
JNI_PeerConnection_GetLocalDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)508 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetLocalDescription(
509     JNIEnv* jni,
510     const JavaParamRef<jobject>& j_pc) {
511   PeerConnectionInterface* pc = ExtractNativePC(jni, j_pc);
512   // It's only safe to operate on SessionDescriptionInterface on the
513   // signaling thread, but `jni` may only be used on the current thread, so we
514   // must do this odd dance.
515   std::string sdp;
516   std::string type;
517   pc->signaling_thread()->BlockingCall([pc, &sdp, &type] {
518     const SessionDescriptionInterface* desc = pc->local_description();
519     if (desc) {
520       RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
521       type = desc->type();
522     }
523   });
524   return sdp.empty() ? nullptr : NativeToJavaSessionDescription(jni, sdp, type);
525 }
526 
JNI_PeerConnection_GetRemoteDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)527 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetRemoteDescription(
528     JNIEnv* jni,
529     const JavaParamRef<jobject>& j_pc) {
530   PeerConnectionInterface* pc = ExtractNativePC(jni, j_pc);
531   // It's only safe to operate on SessionDescriptionInterface on the
532   // signaling thread, but `jni` may only be used on the current thread, so we
533   // must do this odd dance.
534   std::string sdp;
535   std::string type;
536   pc->signaling_thread()->BlockingCall([pc, &sdp, &type] {
537     const SessionDescriptionInterface* desc = pc->remote_description();
538     if (desc) {
539       RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
540       type = desc->type();
541     }
542   });
543   return sdp.empty() ? nullptr : NativeToJavaSessionDescription(jni, sdp, type);
544 }
545 
JNI_PeerConnection_GetCertificate(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)546 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetCertificate(
547     JNIEnv* jni,
548     const JavaParamRef<jobject>& j_pc) {
549   const PeerConnectionInterface::RTCConfiguration rtc_config =
550       ExtractNativePC(jni, j_pc)->GetConfiguration();
551   rtc::scoped_refptr<rtc::RTCCertificate> certificate =
552       rtc_config.certificates[0];
553   return NativeToJavaRTCCertificatePEM(jni, certificate->ToPEM());
554 }
555 
JNI_PeerConnection_CreateDataChannel(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_label,const JavaParamRef<jobject> & j_init)556 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateDataChannel(
557     JNIEnv* jni,
558     const JavaParamRef<jobject>& j_pc,
559     const JavaParamRef<jstring>& j_label,
560     const JavaParamRef<jobject>& j_init) {
561   DataChannelInit init = JavaToNativeDataChannelInit(jni, j_init);
562   auto result = ExtractNativePC(jni, j_pc)->CreateDataChannelOrError(
563       JavaToNativeString(jni, j_label), &init);
564   if (!result.ok()) {
565     return WrapNativeDataChannel(jni, nullptr);
566   }
567   return WrapNativeDataChannel(jni, result.MoveValue());
568 }
569 
JNI_PeerConnection_CreateOffer(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_constraints)570 static void JNI_PeerConnection_CreateOffer(
571     JNIEnv* jni,
572     const JavaParamRef<jobject>& j_pc,
573     const JavaParamRef<jobject>& j_observer,
574     const JavaParamRef<jobject>& j_constraints) {
575   std::unique_ptr<MediaConstraints> constraints =
576       JavaToNativeMediaConstraints(jni, j_constraints);
577   auto observer = rtc::make_ref_counted<CreateSdpObserverJni>(
578       jni, j_observer, std::move(constraints));
579   PeerConnectionInterface::RTCOfferAnswerOptions options;
580   CopyConstraintsIntoOfferAnswerOptions(observer->constraints(), &options);
581   ExtractNativePC(jni, j_pc)->CreateOffer(observer.get(), options);
582 }
583 
JNI_PeerConnection_CreateAnswer(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_constraints)584 static void JNI_PeerConnection_CreateAnswer(
585     JNIEnv* jni,
586     const JavaParamRef<jobject>& j_pc,
587     const JavaParamRef<jobject>& j_observer,
588     const JavaParamRef<jobject>& j_constraints) {
589   std::unique_ptr<MediaConstraints> constraints =
590       JavaToNativeMediaConstraints(jni, j_constraints);
591   auto observer = rtc::make_ref_counted<CreateSdpObserverJni>(
592       jni, j_observer, std::move(constraints));
593   PeerConnectionInterface::RTCOfferAnswerOptions options;
594   CopyConstraintsIntoOfferAnswerOptions(observer->constraints(), &options);
595   ExtractNativePC(jni, j_pc)->CreateAnswer(observer.get(), options);
596 }
597 
JNI_PeerConnection_SetLocalDescriptionAutomatically(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer)598 static void JNI_PeerConnection_SetLocalDescriptionAutomatically(
599     JNIEnv* jni,
600     const JavaParamRef<jobject>& j_pc,
601     const JavaParamRef<jobject>& j_observer) {
602   auto observer =
603       rtc::make_ref_counted<SetLocalSdpObserverJni>(jni, j_observer);
604   ExtractNativePC(jni, j_pc)->SetLocalDescription(observer);
605 }
606 
JNI_PeerConnection_SetLocalDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_sdp)607 static void JNI_PeerConnection_SetLocalDescription(
608     JNIEnv* jni,
609     const JavaParamRef<jobject>& j_pc,
610     const JavaParamRef<jobject>& j_observer,
611     const JavaParamRef<jobject>& j_sdp) {
612   auto observer =
613       rtc::make_ref_counted<SetLocalSdpObserverJni>(jni, j_observer);
614   ExtractNativePC(jni, j_pc)->SetLocalDescription(
615       JavaToNativeSessionDescription(jni, j_sdp), observer);
616 }
617 
JNI_PeerConnection_SetRemoteDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_sdp)618 static void JNI_PeerConnection_SetRemoteDescription(
619     JNIEnv* jni,
620     const JavaParamRef<jobject>& j_pc,
621     const JavaParamRef<jobject>& j_observer,
622     const JavaParamRef<jobject>& j_sdp) {
623   auto observer =
624       rtc::make_ref_counted<SetRemoteSdpObserverJni>(jni, j_observer);
625   ExtractNativePC(jni, j_pc)->SetRemoteDescription(
626       JavaToNativeSessionDescription(jni, j_sdp), observer);
627 }
628 
JNI_PeerConnection_RestartIce(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)629 static void JNI_PeerConnection_RestartIce(JNIEnv* jni,
630                                           const JavaParamRef<jobject>& j_pc) {
631   ExtractNativePC(jni, j_pc)->RestartIce();
632 }
633 
JNI_PeerConnection_SetAudioPlayout(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jboolean playout)634 static void JNI_PeerConnection_SetAudioPlayout(
635     JNIEnv* jni,
636     const JavaParamRef<jobject>& j_pc,
637     jboolean playout) {
638   ExtractNativePC(jni, j_pc)->SetAudioPlayout(playout);
639 }
640 
JNI_PeerConnection_SetAudioRecording(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jboolean recording)641 static void JNI_PeerConnection_SetAudioRecording(
642     JNIEnv* jni,
643     const JavaParamRef<jobject>& j_pc,
644     jboolean recording) {
645   ExtractNativePC(jni, j_pc)->SetAudioRecording(recording);
646 }
647 
JNI_PeerConnection_SetConfiguration(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_rtc_config)648 static jboolean JNI_PeerConnection_SetConfiguration(
649     JNIEnv* jni,
650     const JavaParamRef<jobject>& j_pc,
651     const JavaParamRef<jobject>& j_rtc_config) {
652   // Need to merge constraints into RTCConfiguration again, which are stored
653   // in the OwnedPeerConnection object.
654   OwnedPeerConnection* owned_pc = reinterpret_cast<OwnedPeerConnection*>(
655       Java_PeerConnection_getNativeOwnedPeerConnection(jni, j_pc));
656   PeerConnectionInterface::RTCConfiguration rtc_config(
657       PeerConnectionInterface::RTCConfigurationType::kAggressive);
658   JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
659   if (owned_pc->constraints()) {
660     CopyConstraintsIntoRtcConfiguration(owned_pc->constraints(), &rtc_config);
661   }
662   return owned_pc->pc()->SetConfiguration(rtc_config).ok();
663 }
664 
JNI_PeerConnection_AddIceCandidate(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_sdp_mid,jint j_sdp_mline_index,const JavaParamRef<jstring> & j_candidate_sdp)665 static jboolean JNI_PeerConnection_AddIceCandidate(
666     JNIEnv* jni,
667     const JavaParamRef<jobject>& j_pc,
668     const JavaParamRef<jstring>& j_sdp_mid,
669     jint j_sdp_mline_index,
670     const JavaParamRef<jstring>& j_candidate_sdp) {
671   std::string sdp_mid = JavaToNativeString(jni, j_sdp_mid);
672   std::string sdp = JavaToNativeString(jni, j_candidate_sdp);
673   std::unique_ptr<IceCandidateInterface> candidate(
674       CreateIceCandidate(sdp_mid, j_sdp_mline_index, sdp, nullptr));
675   return ExtractNativePC(jni, j_pc)->AddIceCandidate(candidate.get());
676 }
677 
JNI_PeerConnection_AddIceCandidateWithObserver(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_sdp_mid,jint j_sdp_mline_index,const JavaParamRef<jstring> & j_candidate_sdp,const JavaParamRef<jobject> & j_observer)678 static void JNI_PeerConnection_AddIceCandidateWithObserver(
679     JNIEnv* jni,
680     const JavaParamRef<jobject>& j_pc,
681     const JavaParamRef<jstring>& j_sdp_mid,
682     jint j_sdp_mline_index,
683     const JavaParamRef<jstring>& j_candidate_sdp,
684     const JavaParamRef<jobject>& j_observer) {
685   std::string sdp_mid = JavaToNativeString(jni, j_sdp_mid);
686   std::string sdp = JavaToNativeString(jni, j_candidate_sdp);
687   std::unique_ptr<IceCandidateInterface> candidate(
688       CreateIceCandidate(sdp_mid, j_sdp_mline_index, sdp, nullptr));
689 
690   rtc::scoped_refptr<AddIceCandidateObserverJni> observer(
691       new AddIceCandidateObserverJni(jni, j_observer));
692   ExtractNativePC(jni, j_pc)->AddIceCandidate(
693       std::move(candidate),
694       [observer](RTCError error) { observer->OnComplete(error); });
695 }
696 
JNI_PeerConnection_RemoveIceCandidates(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobjectArray> & j_candidates)697 static jboolean JNI_PeerConnection_RemoveIceCandidates(
698     JNIEnv* jni,
699     const JavaParamRef<jobject>& j_pc,
700     const JavaParamRef<jobjectArray>& j_candidates) {
701   std::vector<cricket::Candidate> candidates =
702       JavaToNativeVector<cricket::Candidate>(jni, j_candidates,
703                                              &JavaToNativeCandidate);
704   return ExtractNativePC(jni, j_pc)->RemoveIceCandidates(candidates);
705 }
706 
JNI_PeerConnection_AddLocalStream(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_stream)707 static jboolean JNI_PeerConnection_AddLocalStream(
708     JNIEnv* jni,
709     const JavaParamRef<jobject>& j_pc,
710     jlong native_stream) {
711   return ExtractNativePC(jni, j_pc)->AddStream(
712       reinterpret_cast<MediaStreamInterface*>(native_stream));
713 }
714 
JNI_PeerConnection_RemoveLocalStream(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_stream)715 static void JNI_PeerConnection_RemoveLocalStream(
716     JNIEnv* jni,
717     const JavaParamRef<jobject>& j_pc,
718     jlong native_stream) {
719   ExtractNativePC(jni, j_pc)->RemoveStream(
720       reinterpret_cast<MediaStreamInterface*>(native_stream));
721 }
722 
JNI_PeerConnection_CreateSender(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_kind,const JavaParamRef<jstring> & j_stream_id)723 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateSender(
724     JNIEnv* jni,
725     const JavaParamRef<jobject>& j_pc,
726     const JavaParamRef<jstring>& j_kind,
727     const JavaParamRef<jstring>& j_stream_id) {
728   std::string kind = JavaToNativeString(jni, j_kind);
729   std::string stream_id = JavaToNativeString(jni, j_stream_id);
730   rtc::scoped_refptr<RtpSenderInterface> sender =
731       ExtractNativePC(jni, j_pc)->CreateSender(kind, stream_id);
732   return NativeToJavaRtpSender(jni, sender);
733 }
734 
JNI_PeerConnection_GetSenders(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)735 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetSenders(
736     JNIEnv* jni,
737     const JavaParamRef<jobject>& j_pc) {
738   return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetSenders(),
739                           &NativeToJavaRtpSender);
740 }
741 
JNI_PeerConnection_GetReceivers(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)742 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetReceivers(
743     JNIEnv* jni,
744     const JavaParamRef<jobject>& j_pc) {
745   return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetReceivers(),
746                           &NativeToJavaRtpReceiver);
747 }
748 
JNI_PeerConnection_GetTransceivers(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)749 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetTransceivers(
750     JNIEnv* jni,
751     const JavaParamRef<jobject>& j_pc) {
752   return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetTransceivers(),
753                           &NativeToJavaRtpTransceiver);
754 }
755 
JNI_PeerConnection_AddTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const jlong native_track,const JavaParamRef<jobject> & j_stream_labels)756 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTrack(
757     JNIEnv* jni,
758     const JavaParamRef<jobject>& j_pc,
759     const jlong native_track,
760     const JavaParamRef<jobject>& j_stream_labels) {
761   RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
762       ExtractNativePC(jni, j_pc)->AddTrack(
763           rtc::scoped_refptr<MediaStreamTrackInterface>(
764               reinterpret_cast<MediaStreamTrackInterface*>(native_track)),
765           JavaListToNativeVector<std::string, jstring>(jni, j_stream_labels,
766                                                        &JavaToNativeString));
767   if (!result.ok()) {
768     RTC_LOG(LS_ERROR) << "Failed to add track: " << result.error().message();
769     return nullptr;
770   } else {
771     return NativeToJavaRtpSender(jni, result.MoveValue());
772   }
773 }
774 
JNI_PeerConnection_RemoveTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_sender)775 static jboolean JNI_PeerConnection_RemoveTrack(
776     JNIEnv* jni,
777     const JavaParamRef<jobject>& j_pc,
778     jlong native_sender) {
779   return ExtractNativePC(jni, j_pc)
780       ->RemoveTrackOrError(rtc::scoped_refptr<RtpSenderInterface>(
781           reinterpret_cast<RtpSenderInterface*>(native_sender)))
782       .ok();
783 }
784 
JNI_PeerConnection_AddTransceiverWithTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_track,const JavaParamRef<jobject> & j_init)785 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTransceiverWithTrack(
786     JNIEnv* jni,
787     const JavaParamRef<jobject>& j_pc,
788     jlong native_track,
789     const JavaParamRef<jobject>& j_init) {
790   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
791       ExtractNativePC(jni, j_pc)->AddTransceiver(
792           rtc::scoped_refptr<MediaStreamTrackInterface>(
793               reinterpret_cast<MediaStreamTrackInterface*>(native_track)),
794           JavaToNativeRtpTransceiverInit(jni, j_init));
795   if (!result.ok()) {
796     RTC_LOG(LS_ERROR) << "Failed to add transceiver: "
797                       << result.error().message();
798     return nullptr;
799   } else {
800     return NativeToJavaRtpTransceiver(jni, result.MoveValue());
801   }
802 }
803 
JNI_PeerConnection_AddTransceiverOfType(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_media_type,const JavaParamRef<jobject> & j_init)804 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTransceiverOfType(
805     JNIEnv* jni,
806     const JavaParamRef<jobject>& j_pc,
807     const JavaParamRef<jobject>& j_media_type,
808     const JavaParamRef<jobject>& j_init) {
809   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
810       ExtractNativePC(jni, j_pc)->AddTransceiver(
811           JavaToNativeMediaType(jni, j_media_type),
812           JavaToNativeRtpTransceiverInit(jni, j_init));
813   if (!result.ok()) {
814     RTC_LOG(LS_ERROR) << "Failed to add transceiver: "
815                       << result.error().message();
816     return nullptr;
817   } else {
818     return NativeToJavaRtpTransceiver(jni, result.MoveValue());
819   }
820 }
821 
JNI_PeerConnection_OldGetStats(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,jlong native_track)822 static jboolean JNI_PeerConnection_OldGetStats(
823     JNIEnv* jni,
824     const JavaParamRef<jobject>& j_pc,
825     const JavaParamRef<jobject>& j_observer,
826     jlong native_track) {
827   auto observer = rtc::make_ref_counted<StatsObserverJni>(jni, j_observer);
828   return ExtractNativePC(jni, j_pc)->GetStats(
829       observer.get(),
830       reinterpret_cast<MediaStreamTrackInterface*>(native_track),
831       PeerConnectionInterface::kStatsOutputLevelStandard);
832 }
833 
JNI_PeerConnection_NewGetStats(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_callback)834 static void JNI_PeerConnection_NewGetStats(
835     JNIEnv* jni,
836     const JavaParamRef<jobject>& j_pc,
837     const JavaParamRef<jobject>& j_callback) {
838   auto callback =
839       rtc::make_ref_counted<RTCStatsCollectorCallbackWrapper>(jni, j_callback);
840   ExtractNativePC(jni, j_pc)->GetStats(callback.get());
841 }
842 
JNI_PeerConnection_NewGetStatsSender(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_sender,const JavaParamRef<jobject> & j_callback)843 static void JNI_PeerConnection_NewGetStatsSender(
844     JNIEnv* jni,
845     const JavaParamRef<jobject>& j_pc,
846     jlong native_sender,
847     const JavaParamRef<jobject>& j_callback) {
848   auto callback =
849       rtc::make_ref_counted<RTCStatsCollectorCallbackWrapper>(jni, j_callback);
850   ExtractNativePC(jni, j_pc)->GetStats(
851       rtc::scoped_refptr<RtpSenderInterface>(
852           reinterpret_cast<RtpSenderInterface*>(native_sender)),
853       rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper>(callback.get()));
854 }
855 
JNI_PeerConnection_NewGetStatsReceiver(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_receiver,const JavaParamRef<jobject> & j_callback)856 static void JNI_PeerConnection_NewGetStatsReceiver(
857     JNIEnv* jni,
858     const JavaParamRef<jobject>& j_pc,
859     jlong native_receiver,
860     const JavaParamRef<jobject>& j_callback) {
861   auto callback =
862       rtc::make_ref_counted<RTCStatsCollectorCallbackWrapper>(jni, j_callback);
863   ExtractNativePC(jni, j_pc)->GetStats(
864       rtc::scoped_refptr<RtpReceiverInterface>(
865           reinterpret_cast<RtpReceiverInterface*>(native_receiver)),
866       rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper>(callback.get()));
867 }
868 
JNI_PeerConnection_SetBitrate(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_min,const JavaParamRef<jobject> & j_current,const JavaParamRef<jobject> & j_max)869 static jboolean JNI_PeerConnection_SetBitrate(
870     JNIEnv* jni,
871     const JavaParamRef<jobject>& j_pc,
872     const JavaParamRef<jobject>& j_min,
873     const JavaParamRef<jobject>& j_current,
874     const JavaParamRef<jobject>& j_max) {
875   BitrateSettings params;
876   params.min_bitrate_bps = JavaToNativeOptionalInt(jni, j_min);
877   params.start_bitrate_bps = JavaToNativeOptionalInt(jni, j_current);
878   params.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_max);
879   return ExtractNativePC(jni, j_pc)->SetBitrate(params).ok();
880 }
881 
JNI_PeerConnection_StartRtcEventLog(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,int file_descriptor,int max_size_bytes)882 static jboolean JNI_PeerConnection_StartRtcEventLog(
883     JNIEnv* jni,
884     const JavaParamRef<jobject>& j_pc,
885     int file_descriptor,
886     int max_size_bytes) {
887   // TODO(eladalon): It would be better to not allow negative values into PC.
888   const size_t max_size = (max_size_bytes < 0)
889                               ? RtcEventLog::kUnlimitedOutput
890                               : rtc::saturated_cast<size_t>(max_size_bytes);
891   FILE* f = fdopen(file_descriptor, "wb");
892   if (!f) {
893     close(file_descriptor);
894     return false;
895   }
896   return ExtractNativePC(jni, j_pc)->StartRtcEventLog(
897       std::make_unique<RtcEventLogOutputFile>(f, max_size));
898 }
899 
JNI_PeerConnection_StopRtcEventLog(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)900 static void JNI_PeerConnection_StopRtcEventLog(
901     JNIEnv* jni,
902     const JavaParamRef<jobject>& j_pc) {
903   ExtractNativePC(jni, j_pc)->StopRtcEventLog();
904 }
905 
JNI_PeerConnection_SignalingState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)906 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_SignalingState(
907     JNIEnv* env,
908     const JavaParamRef<jobject>& j_pc) {
909   return Java_SignalingState_fromNativeIndex(
910       env, ExtractNativePC(env, j_pc)->signaling_state());
911 }
912 
JNI_PeerConnection_IceConnectionState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)913 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceConnectionState(
914     JNIEnv* env,
915     const JavaParamRef<jobject>& j_pc) {
916   return Java_IceConnectionState_fromNativeIndex(
917       env, ExtractNativePC(env, j_pc)->ice_connection_state());
918 }
919 
JNI_PeerConnection_ConnectionState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)920 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_ConnectionState(
921     JNIEnv* env,
922     const JavaParamRef<jobject>& j_pc) {
923   return Java_PeerConnectionState_fromNativeIndex(
924       env,
925       static_cast<int>(ExtractNativePC(env, j_pc)->peer_connection_state()));
926 }
927 
JNI_PeerConnection_IceGatheringState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)928 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceGatheringState(
929     JNIEnv* env,
930     const JavaParamRef<jobject>& j_pc) {
931   return Java_IceGatheringState_fromNativeIndex(
932       env, ExtractNativePC(env, j_pc)->ice_gathering_state());
933 }
934 
JNI_PeerConnection_Close(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)935 static void JNI_PeerConnection_Close(JNIEnv* jni,
936                                      const JavaParamRef<jobject>& j_pc) {
937   ExtractNativePC(jni, j_pc)->Close();
938 }
939 
940 }  // namespace jni
941 }  // namespace webrtc
942