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/PeerConnection_jni.h"
45 #include "sdk/android/native_api/jni/java_types.h"
46 #include "sdk/android/src/jni/jni_helpers.h"
47 #include "sdk/android/src/jni/pc/crypto_options.h"
48 #include "sdk/android/src/jni/pc/data_channel.h"
49 #include "sdk/android/src/jni/pc/ice_candidate.h"
50 #include "sdk/android/src/jni/pc/media_constraints.h"
51 #include "sdk/android/src/jni/pc/media_stream_track.h"
52 #include "sdk/android/src/jni/pc/rtc_certificate.h"
53 #include "sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.h"
54 #include "sdk/android/src/jni/pc/rtp_sender.h"
55 #include "sdk/android/src/jni/pc/sdp_observer.h"
56 #include "sdk/android/src/jni/pc/session_description.h"
57 #include "sdk/android/src/jni/pc/stats_observer.h"
58 #include "sdk/android/src/jni/pc/turn_customizer.h"
59 
60 namespace webrtc {
61 namespace jni {
62 
63 namespace {
64 
ExtractNativePC(JNIEnv * jni,const JavaRef<jobject> & j_pc)65 PeerConnectionInterface* ExtractNativePC(JNIEnv* jni,
66                                          const JavaRef<jobject>& j_pc) {
67   return reinterpret_cast<OwnedPeerConnection*>(
68              Java_PeerConnection_getNativeOwnedPeerConnection(jni, j_pc))
69       ->pc();
70 }
71 
JavaToNativeIceServers(JNIEnv * jni,const JavaRef<jobject> & j_ice_servers)72 PeerConnectionInterface::IceServers JavaToNativeIceServers(
73     JNIEnv* jni,
74     const JavaRef<jobject>& j_ice_servers) {
75   PeerConnectionInterface::IceServers ice_servers;
76   for (const JavaRef<jobject>& j_ice_server : Iterable(jni, j_ice_servers)) {
77     ScopedJavaLocalRef<jobject> j_ice_server_tls_cert_policy =
78         Java_IceServer_getTlsCertPolicy(jni, j_ice_server);
79     ScopedJavaLocalRef<jobject> urls =
80         Java_IceServer_getUrls(jni, j_ice_server);
81     ScopedJavaLocalRef<jstring> username =
82         Java_IceServer_getUsername(jni, j_ice_server);
83     ScopedJavaLocalRef<jstring> password =
84         Java_IceServer_getPassword(jni, j_ice_server);
85     PeerConnectionInterface::TlsCertPolicy tls_cert_policy =
86         JavaToNativeTlsCertPolicy(jni, j_ice_server_tls_cert_policy);
87     ScopedJavaLocalRef<jstring> hostname =
88         Java_IceServer_getHostname(jni, j_ice_server);
89     ScopedJavaLocalRef<jobject> tls_alpn_protocols =
90         Java_IceServer_getTlsAlpnProtocols(jni, j_ice_server);
91     ScopedJavaLocalRef<jobject> tls_elliptic_curves =
92         Java_IceServer_getTlsEllipticCurves(jni, j_ice_server);
93     PeerConnectionInterface::IceServer server;
94     server.urls = JavaListToNativeVector<std::string, jstring>(
95         jni, urls, &JavaToNativeString);
96     server.username = JavaToNativeString(jni, username);
97     server.password = JavaToNativeString(jni, password);
98     server.tls_cert_policy = tls_cert_policy;
99     server.hostname = JavaToNativeString(jni, hostname);
100     server.tls_alpn_protocols = JavaListToNativeVector<std::string, jstring>(
101         jni, tls_alpn_protocols, &JavaToNativeString);
102     server.tls_elliptic_curves = JavaListToNativeVector<std::string, jstring>(
103         jni, tls_elliptic_curves, &JavaToNativeString);
104     ice_servers.push_back(server);
105   }
106   return ice_servers;
107 }
108 
JavaToNativeSdpSemantics(JNIEnv * jni,const JavaRef<jobject> & j_sdp_semantics)109 SdpSemantics JavaToNativeSdpSemantics(JNIEnv* jni,
110                                       const JavaRef<jobject>& j_sdp_semantics) {
111   std::string enum_name = GetJavaEnumName(jni, j_sdp_semantics);
112 
113   if (enum_name == "PLAN_B")
114     return SdpSemantics::kPlanB;
115 
116   if (enum_name == "UNIFIED_PLAN")
117     return SdpSemantics::kUnifiedPlan;
118 
119   RTC_NOTREACHED();
120   return SdpSemantics::kPlanB;
121 }
122 
NativeToJavaCandidatePairChange(JNIEnv * env,const cricket::CandidatePairChangeEvent & event)123 ScopedJavaLocalRef<jobject> NativeToJavaCandidatePairChange(
124     JNIEnv* env,
125     const cricket::CandidatePairChangeEvent& event) {
126   const auto& selected_pair = event.selected_candidate_pair;
127   return Java_CandidatePairChangeEvent_Constructor(
128       env, NativeToJavaCandidate(env, selected_pair.local_candidate()),
129       NativeToJavaCandidate(env, selected_pair.remote_candidate()),
130       static_cast<int>(event.last_data_received_ms),
131       NativeToJavaString(env, event.reason));
132 }
133 
134 }  // namespace
135 
NativeToJavaAdapterType(JNIEnv * env,int adapterType)136 ScopedJavaLocalRef<jobject> NativeToJavaAdapterType(JNIEnv* env,
137                                                     int adapterType) {
138   return Java_AdapterType_fromNativeIndex(env, adapterType);
139 }
140 
JavaToNativeRTCConfiguration(JNIEnv * jni,const JavaRef<jobject> & j_rtc_config,PeerConnectionInterface::RTCConfiguration * rtc_config)141 void JavaToNativeRTCConfiguration(
142     JNIEnv* jni,
143     const JavaRef<jobject>& j_rtc_config,
144     PeerConnectionInterface::RTCConfiguration* rtc_config) {
145   ScopedJavaLocalRef<jobject> j_ice_transports_type =
146       Java_RTCConfiguration_getIceTransportsType(jni, j_rtc_config);
147   ScopedJavaLocalRef<jobject> j_bundle_policy =
148       Java_RTCConfiguration_getBundlePolicy(jni, j_rtc_config);
149   ScopedJavaLocalRef<jobject> j_rtcp_mux_policy =
150       Java_RTCConfiguration_getRtcpMuxPolicy(jni, j_rtc_config);
151   ScopedJavaLocalRef<jobject> j_rtc_certificate =
152       Java_RTCConfiguration_getCertificate(jni, j_rtc_config);
153   ScopedJavaLocalRef<jobject> j_tcp_candidate_policy =
154       Java_RTCConfiguration_getTcpCandidatePolicy(jni, j_rtc_config);
155   ScopedJavaLocalRef<jobject> j_candidate_network_policy =
156       Java_RTCConfiguration_getCandidateNetworkPolicy(jni, j_rtc_config);
157   ScopedJavaLocalRef<jobject> j_ice_servers =
158       Java_RTCConfiguration_getIceServers(jni, j_rtc_config);
159   ScopedJavaLocalRef<jobject> j_continual_gathering_policy =
160       Java_RTCConfiguration_getContinualGatheringPolicy(jni, j_rtc_config);
161   ScopedJavaLocalRef<jobject> j_turn_port_prune_policy =
162       Java_RTCConfiguration_getTurnPortPrunePolicy(jni, j_rtc_config);
163   ScopedJavaLocalRef<jobject> j_turn_customizer =
164       Java_RTCConfiguration_getTurnCustomizer(jni, j_rtc_config);
165   ScopedJavaLocalRef<jobject> j_network_preference =
166       Java_RTCConfiguration_getNetworkPreference(jni, j_rtc_config);
167   ScopedJavaLocalRef<jobject> j_sdp_semantics =
168       Java_RTCConfiguration_getSdpSemantics(jni, j_rtc_config);
169   ScopedJavaLocalRef<jobject> j_crypto_options =
170       Java_RTCConfiguration_getCryptoOptions(jni, j_rtc_config);
171 
172   rtc_config->type = JavaToNativeIceTransportsType(jni, j_ice_transports_type);
173   rtc_config->bundle_policy = JavaToNativeBundlePolicy(jni, j_bundle_policy);
174   rtc_config->rtcp_mux_policy =
175       JavaToNativeRtcpMuxPolicy(jni, j_rtcp_mux_policy);
176   if (!j_rtc_certificate.is_null()) {
177     rtc::scoped_refptr<rtc::RTCCertificate> certificate =
178         rtc::RTCCertificate::FromPEM(
179             JavaToNativeRTCCertificatePEM(jni, j_rtc_certificate));
180     RTC_CHECK(certificate != nullptr) << "supplied certificate is malformed.";
181     rtc_config->certificates.push_back(certificate);
182   }
183   rtc_config->tcp_candidate_policy =
184       JavaToNativeTcpCandidatePolicy(jni, j_tcp_candidate_policy);
185   rtc_config->candidate_network_policy =
186       JavaToNativeCandidateNetworkPolicy(jni, j_candidate_network_policy);
187   rtc_config->servers = JavaToNativeIceServers(jni, j_ice_servers);
188   rtc_config->audio_jitter_buffer_max_packets =
189       Java_RTCConfiguration_getAudioJitterBufferMaxPackets(jni, j_rtc_config);
190   rtc_config->audio_jitter_buffer_fast_accelerate =
191       Java_RTCConfiguration_getAudioJitterBufferFastAccelerate(jni,
192                                                                j_rtc_config);
193   rtc_config->ice_connection_receiving_timeout =
194       Java_RTCConfiguration_getIceConnectionReceivingTimeout(jni, j_rtc_config);
195   rtc_config->ice_backup_candidate_pair_ping_interval =
196       Java_RTCConfiguration_getIceBackupCandidatePairPingInterval(jni,
197                                                                   j_rtc_config);
198   rtc_config->continual_gathering_policy =
199       JavaToNativeContinualGatheringPolicy(jni, j_continual_gathering_policy);
200   rtc_config->ice_candidate_pool_size =
201       Java_RTCConfiguration_getIceCandidatePoolSize(jni, j_rtc_config);
202   rtc_config->prune_turn_ports =
203       Java_RTCConfiguration_getPruneTurnPorts(jni, j_rtc_config);
204   rtc_config->turn_port_prune_policy =
205       JavaToNativePortPrunePolicy(jni, j_turn_port_prune_policy);
206   rtc_config->presume_writable_when_fully_relayed =
207       Java_RTCConfiguration_getPresumeWritableWhenFullyRelayed(jni,
208                                                                j_rtc_config);
209   rtc_config->surface_ice_candidates_on_ice_transport_type_changed =
210       Java_RTCConfiguration_getSurfaceIceCandidatesOnIceTransportTypeChanged(
211           jni, j_rtc_config);
212   ScopedJavaLocalRef<jobject> j_ice_check_interval_strong_connectivity =
213       Java_RTCConfiguration_getIceCheckIntervalStrongConnectivity(jni,
214                                                                   j_rtc_config);
215   rtc_config->ice_check_interval_strong_connectivity =
216       JavaToNativeOptionalInt(jni, j_ice_check_interval_strong_connectivity);
217   ScopedJavaLocalRef<jobject> j_ice_check_interval_weak_connectivity =
218       Java_RTCConfiguration_getIceCheckIntervalWeakConnectivity(jni,
219                                                                 j_rtc_config);
220   rtc_config->ice_check_interval_weak_connectivity =
221       JavaToNativeOptionalInt(jni, j_ice_check_interval_weak_connectivity);
222   ScopedJavaLocalRef<jobject> j_ice_check_min_interval =
223       Java_RTCConfiguration_getIceCheckMinInterval(jni, j_rtc_config);
224   rtc_config->ice_check_min_interval =
225       JavaToNativeOptionalInt(jni, j_ice_check_min_interval);
226   ScopedJavaLocalRef<jobject> j_ice_unwritable_timeout =
227       Java_RTCConfiguration_getIceUnwritableTimeout(jni, j_rtc_config);
228   rtc_config->ice_unwritable_timeout =
229       JavaToNativeOptionalInt(jni, j_ice_unwritable_timeout);
230   ScopedJavaLocalRef<jobject> j_ice_unwritable_min_checks =
231       Java_RTCConfiguration_getIceUnwritableMinChecks(jni, j_rtc_config);
232   rtc_config->ice_unwritable_min_checks =
233       JavaToNativeOptionalInt(jni, j_ice_unwritable_min_checks);
234   ScopedJavaLocalRef<jobject> j_stun_candidate_keepalive_interval =
235       Java_RTCConfiguration_getStunCandidateKeepaliveInterval(jni,
236                                                               j_rtc_config);
237   rtc_config->stun_candidate_keepalive_interval =
238       JavaToNativeOptionalInt(jni, j_stun_candidate_keepalive_interval);
239   rtc_config->disable_ipv6_on_wifi =
240       Java_RTCConfiguration_getDisableIPv6OnWifi(jni, j_rtc_config);
241   rtc_config->max_ipv6_networks =
242       Java_RTCConfiguration_getMaxIPv6Networks(jni, j_rtc_config);
243 
244   rtc_config->turn_customizer = GetNativeTurnCustomizer(jni, j_turn_customizer);
245 
246   rtc_config->disable_ipv6 =
247       Java_RTCConfiguration_getDisableIpv6(jni, j_rtc_config);
248   rtc_config->media_config.enable_dscp =
249       Java_RTCConfiguration_getEnableDscp(jni, j_rtc_config);
250   rtc_config->media_config.video.enable_cpu_adaptation =
251       Java_RTCConfiguration_getEnableCpuOveruseDetection(jni, j_rtc_config);
252   rtc_config->enable_rtp_data_channel =
253       Java_RTCConfiguration_getEnableRtpDataChannel(jni, j_rtc_config);
254   rtc_config->media_config.video.suspend_below_min_bitrate =
255       Java_RTCConfiguration_getSuspendBelowMinBitrate(jni, j_rtc_config);
256   rtc_config->screencast_min_bitrate = JavaToNativeOptionalInt(
257       jni, Java_RTCConfiguration_getScreencastMinBitrate(jni, j_rtc_config));
258   rtc_config->combined_audio_video_bwe = JavaToNativeOptionalBool(
259       jni, Java_RTCConfiguration_getCombinedAudioVideoBwe(jni, j_rtc_config));
260   rtc_config->enable_dtls_srtp = JavaToNativeOptionalBool(
261       jni, Java_RTCConfiguration_getEnableDtlsSrtp(jni, j_rtc_config));
262   rtc_config->network_preference =
263       JavaToNativeNetworkPreference(jni, j_network_preference);
264   rtc_config->sdp_semantics = JavaToNativeSdpSemantics(jni, j_sdp_semantics);
265   rtc_config->active_reset_srtp_params =
266       Java_RTCConfiguration_getActiveResetSrtpParams(jni, j_rtc_config);
267   rtc_config->use_media_transport =
268       Java_RTCConfiguration_getUseMediaTransport(jni, j_rtc_config);
269   rtc_config->use_media_transport_for_data_channels =
270       Java_RTCConfiguration_getUseMediaTransportForDataChannels(jni,
271                                                                 j_rtc_config);
272   rtc_config->crypto_options =
273       JavaToNativeOptionalCryptoOptions(jni, j_crypto_options);
274 
275   rtc_config->allow_codec_switching = JavaToNativeOptionalBool(
276       jni, Java_RTCConfiguration_getAllowCodecSwitching(jni, j_rtc_config));
277 
278   ScopedJavaLocalRef<jstring> j_turn_logging_id =
279       Java_RTCConfiguration_getTurnLoggingId(jni, j_rtc_config);
280   if (!IsNull(jni, j_turn_logging_id)) {
281     rtc_config->turn_logging_id = JavaToNativeString(jni, j_turn_logging_id);
282   }
283 }
284 
GetRtcConfigKeyType(JNIEnv * env,const JavaRef<jobject> & j_rtc_config)285 rtc::KeyType GetRtcConfigKeyType(JNIEnv* env,
286                                  const JavaRef<jobject>& j_rtc_config) {
287   return JavaToNativeKeyType(
288       env, Java_RTCConfiguration_getKeyType(env, j_rtc_config));
289 }
290 
PeerConnectionObserverJni(JNIEnv * jni,const JavaRef<jobject> & j_observer)291 PeerConnectionObserverJni::PeerConnectionObserverJni(
292     JNIEnv* jni,
293     const JavaRef<jobject>& j_observer)
294     : j_observer_global_(jni, j_observer) {}
295 
296 PeerConnectionObserverJni::~PeerConnectionObserverJni() = default;
297 
OnIceCandidate(const IceCandidateInterface * candidate)298 void PeerConnectionObserverJni::OnIceCandidate(
299     const IceCandidateInterface* candidate) {
300   JNIEnv* env = AttachCurrentThreadIfNeeded();
301   Java_Observer_onIceCandidate(env, j_observer_global_,
302                                NativeToJavaIceCandidate(env, *candidate));
303 }
304 
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)305 void PeerConnectionObserverJni::OnIceCandidatesRemoved(
306     const std::vector<cricket::Candidate>& candidates) {
307   JNIEnv* env = AttachCurrentThreadIfNeeded();
308   Java_Observer_onIceCandidatesRemoved(
309       env, j_observer_global_, NativeToJavaCandidateArray(env, candidates));
310 }
311 
OnSignalingChange(PeerConnectionInterface::SignalingState new_state)312 void PeerConnectionObserverJni::OnSignalingChange(
313     PeerConnectionInterface::SignalingState new_state) {
314   JNIEnv* env = AttachCurrentThreadIfNeeded();
315   Java_Observer_onSignalingChange(
316       env, j_observer_global_,
317       Java_SignalingState_fromNativeIndex(env, new_state));
318 }
319 
OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)320 void PeerConnectionObserverJni::OnIceConnectionChange(
321     PeerConnectionInterface::IceConnectionState new_state) {
322   JNIEnv* env = AttachCurrentThreadIfNeeded();
323   Java_Observer_onIceConnectionChange(
324       env, j_observer_global_,
325       Java_IceConnectionState_fromNativeIndex(env, new_state));
326 }
327 
OnStandardizedIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)328 void PeerConnectionObserverJni::OnStandardizedIceConnectionChange(
329     PeerConnectionInterface::IceConnectionState new_state) {
330   JNIEnv* env = AttachCurrentThreadIfNeeded();
331   Java_Observer_onStandardizedIceConnectionChange(
332       env, j_observer_global_,
333       Java_IceConnectionState_fromNativeIndex(env, new_state));
334 }
335 
OnConnectionChange(PeerConnectionInterface::PeerConnectionState new_state)336 void PeerConnectionObserverJni::OnConnectionChange(
337     PeerConnectionInterface::PeerConnectionState new_state) {
338   JNIEnv* env = AttachCurrentThreadIfNeeded();
339   Java_Observer_onConnectionChange(env, j_observer_global_,
340                                    Java_PeerConnectionState_fromNativeIndex(
341                                        env, static_cast<int>(new_state)));
342 }
343 
OnIceConnectionReceivingChange(bool receiving)344 void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) {
345   JNIEnv* env = AttachCurrentThreadIfNeeded();
346   Java_Observer_onIceConnectionReceivingChange(env, j_observer_global_,
347                                                receiving);
348 }
349 
OnIceSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent & event)350 void PeerConnectionObserverJni::OnIceSelectedCandidatePairChanged(
351     const cricket::CandidatePairChangeEvent& event) {
352   JNIEnv* env = AttachCurrentThreadIfNeeded();
353   Java_Observer_onSelectedCandidatePairChanged(
354       env, j_observer_global_, NativeToJavaCandidatePairChange(env, event));
355 }
356 
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)357 void PeerConnectionObserverJni::OnIceGatheringChange(
358     PeerConnectionInterface::IceGatheringState new_state) {
359   JNIEnv* env = AttachCurrentThreadIfNeeded();
360   Java_Observer_onIceGatheringChange(
361       env, j_observer_global_,
362       Java_IceGatheringState_fromNativeIndex(env, new_state));
363 }
364 
OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream)365 void PeerConnectionObserverJni::OnAddStream(
366     rtc::scoped_refptr<MediaStreamInterface> stream) {
367   JNIEnv* env = AttachCurrentThreadIfNeeded();
368   Java_Observer_onAddStream(
369       env, j_observer_global_,
370       GetOrCreateJavaStream(env, stream).j_media_stream());
371 }
372 
OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream)373 void PeerConnectionObserverJni::OnRemoveStream(
374     rtc::scoped_refptr<MediaStreamInterface> stream) {
375   JNIEnv* env = AttachCurrentThreadIfNeeded();
376   NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
377   RTC_CHECK(it != remote_streams_.end()) << "unexpected stream: " << stream;
378   Java_Observer_onRemoveStream(env, j_observer_global_,
379                                it->second.j_media_stream());
380   remote_streams_.erase(it);
381 }
382 
OnDataChannel(rtc::scoped_refptr<DataChannelInterface> channel)383 void PeerConnectionObserverJni::OnDataChannel(
384     rtc::scoped_refptr<DataChannelInterface> channel) {
385   JNIEnv* env = AttachCurrentThreadIfNeeded();
386   Java_Observer_onDataChannel(env, j_observer_global_,
387                               WrapNativeDataChannel(env, channel));
388 }
389 
OnRenegotiationNeeded()390 void PeerConnectionObserverJni::OnRenegotiationNeeded() {
391   JNIEnv* env = AttachCurrentThreadIfNeeded();
392   Java_Observer_onRenegotiationNeeded(env, j_observer_global_);
393 }
394 
OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)395 void PeerConnectionObserverJni::OnAddTrack(
396     rtc::scoped_refptr<RtpReceiverInterface> receiver,
397     const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
398   JNIEnv* env = AttachCurrentThreadIfNeeded();
399   ScopedJavaLocalRef<jobject> j_rtp_receiver =
400       NativeToJavaRtpReceiver(env, receiver);
401   rtp_receivers_.emplace_back(env, j_rtp_receiver);
402 
403   Java_Observer_onAddTrack(env, j_observer_global_, j_rtp_receiver,
404                            NativeToJavaMediaStreamArray(env, streams));
405 }
406 
OnTrack(rtc::scoped_refptr<RtpTransceiverInterface> transceiver)407 void PeerConnectionObserverJni::OnTrack(
408     rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
409   JNIEnv* env = AttachCurrentThreadIfNeeded();
410   ScopedJavaLocalRef<jobject> j_rtp_transceiver =
411       NativeToJavaRtpTransceiver(env, transceiver);
412   rtp_transceivers_.emplace_back(env, j_rtp_transceiver);
413 
414   Java_Observer_onTrack(env, j_observer_global_, j_rtp_transceiver);
415 }
416 
417 // If the NativeToJavaStreamsMap contains the stream, return it.
418 // Otherwise, create a new Java MediaStream.
GetOrCreateJavaStream(JNIEnv * env,const rtc::scoped_refptr<MediaStreamInterface> & stream)419 JavaMediaStream& PeerConnectionObserverJni::GetOrCreateJavaStream(
420     JNIEnv* env,
421     const rtc::scoped_refptr<MediaStreamInterface>& stream) {
422   NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
423   if (it == remote_streams_.end()) {
424     it = remote_streams_
425              .emplace(std::piecewise_construct,
426                       std::forward_as_tuple(stream.get()),
427                       std::forward_as_tuple(env, stream))
428              .first;
429   }
430   return it->second;
431 }
432 
433 ScopedJavaLocalRef<jobjectArray>
NativeToJavaMediaStreamArray(JNIEnv * jni,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)434 PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
435     JNIEnv* jni,
436     const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
437   return NativeToJavaObjectArray(
438       jni, streams, GetMediaStreamClass(jni),
439       [this](JNIEnv* env, rtc::scoped_refptr<MediaStreamInterface> stream)
440           -> const ScopedJavaGlobalRef<jobject>& {
441         return GetOrCreateJavaStream(env, stream).j_media_stream();
442       });
443 }
444 
OwnedPeerConnection(rtc::scoped_refptr<PeerConnectionInterface> peer_connection,std::unique_ptr<PeerConnectionObserver> observer)445 OwnedPeerConnection::OwnedPeerConnection(
446     rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
447     std::unique_ptr<PeerConnectionObserver> observer)
448     : OwnedPeerConnection(peer_connection,
449                           std::move(observer),
450                           nullptr /* constraints */) {}
451 
OwnedPeerConnection(rtc::scoped_refptr<PeerConnectionInterface> peer_connection,std::unique_ptr<PeerConnectionObserver> observer,std::unique_ptr<MediaConstraints> constraints)452 OwnedPeerConnection::OwnedPeerConnection(
453     rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
454     std::unique_ptr<PeerConnectionObserver> observer,
455     std::unique_ptr<MediaConstraints> constraints)
456     : peer_connection_(peer_connection),
457       observer_(std::move(observer)),
458       constraints_(std::move(constraints)) {}
459 
~OwnedPeerConnection()460 OwnedPeerConnection::~OwnedPeerConnection() {
461   // Ensure that PeerConnection is destroyed before the observer.
462   peer_connection_ = nullptr;
463 }
464 
JNI_PeerConnection_CreatePeerConnectionObserver(JNIEnv * jni,const JavaParamRef<jobject> & j_observer)465 static jlong JNI_PeerConnection_CreatePeerConnectionObserver(
466     JNIEnv* jni,
467     const JavaParamRef<jobject>& j_observer) {
468   return jlongFromPointer(new PeerConnectionObserverJni(jni, j_observer));
469 }
470 
JNI_PeerConnection_FreeOwnedPeerConnection(JNIEnv *,jlong j_p)471 static void JNI_PeerConnection_FreeOwnedPeerConnection(
472     JNIEnv*,
473     jlong j_p) {
474   delete reinterpret_cast<OwnedPeerConnection*>(j_p);
475 }
476 
JNI_PeerConnection_GetNativePeerConnection(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)477 static jlong JNI_PeerConnection_GetNativePeerConnection(
478     JNIEnv* jni,
479     const JavaParamRef<jobject>& j_pc) {
480   return jlongFromPointer(ExtractNativePC(jni, j_pc));
481 }
482 
JNI_PeerConnection_GetLocalDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)483 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetLocalDescription(
484     JNIEnv* jni,
485     const JavaParamRef<jobject>& j_pc) {
486   const SessionDescriptionInterface* sdp =
487       ExtractNativePC(jni, j_pc)->local_description();
488   return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
489 }
490 
JNI_PeerConnection_GetRemoteDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)491 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetRemoteDescription(
492     JNIEnv* jni,
493     const JavaParamRef<jobject>& j_pc) {
494   const SessionDescriptionInterface* sdp =
495       ExtractNativePC(jni, j_pc)->remote_description();
496   return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
497 }
498 
JNI_PeerConnection_GetCertificate(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)499 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetCertificate(
500     JNIEnv* jni,
501     const JavaParamRef<jobject>& j_pc) {
502   const PeerConnectionInterface::RTCConfiguration rtc_config =
503       ExtractNativePC(jni, j_pc)->GetConfiguration();
504   rtc::scoped_refptr<rtc::RTCCertificate> certificate =
505       rtc_config.certificates[0];
506   return NativeToJavaRTCCertificatePEM(jni, certificate->ToPEM());
507 }
508 
JNI_PeerConnection_CreateDataChannel(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_label,const JavaParamRef<jobject> & j_init)509 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateDataChannel(
510     JNIEnv* jni,
511     const JavaParamRef<jobject>& j_pc,
512     const JavaParamRef<jstring>& j_label,
513     const JavaParamRef<jobject>& j_init) {
514   DataChannelInit init = JavaToNativeDataChannelInit(jni, j_init);
515   rtc::scoped_refptr<DataChannelInterface> channel(
516       ExtractNativePC(jni, j_pc)->CreateDataChannel(
517           JavaToNativeString(jni, j_label), &init));
518   return WrapNativeDataChannel(jni, channel);
519 }
520 
JNI_PeerConnection_CreateOffer(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_constraints)521 static void JNI_PeerConnection_CreateOffer(
522     JNIEnv* jni,
523     const JavaParamRef<jobject>& j_pc,
524     const JavaParamRef<jobject>& j_observer,
525     const JavaParamRef<jobject>& j_constraints) {
526   std::unique_ptr<MediaConstraints> constraints =
527       JavaToNativeMediaConstraints(jni, j_constraints);
528   rtc::scoped_refptr<CreateSdpObserverJni> observer(
529       new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
530                                                       std::move(constraints)));
531   PeerConnectionInterface::RTCOfferAnswerOptions options;
532   CopyConstraintsIntoOfferAnswerOptions(observer->constraints(), &options);
533   ExtractNativePC(jni, j_pc)->CreateOffer(observer, options);
534 }
535 
JNI_PeerConnection_CreateAnswer(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_constraints)536 static void JNI_PeerConnection_CreateAnswer(
537     JNIEnv* jni,
538     const JavaParamRef<jobject>& j_pc,
539     const JavaParamRef<jobject>& j_observer,
540     const JavaParamRef<jobject>& j_constraints) {
541   std::unique_ptr<MediaConstraints> constraints =
542       JavaToNativeMediaConstraints(jni, j_constraints);
543   rtc::scoped_refptr<CreateSdpObserverJni> observer(
544       new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
545                                                       std::move(constraints)));
546   PeerConnectionInterface::RTCOfferAnswerOptions options;
547   CopyConstraintsIntoOfferAnswerOptions(observer->constraints(), &options);
548   ExtractNativePC(jni, j_pc)->CreateAnswer(observer, options);
549 }
550 
JNI_PeerConnection_SetLocalDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_sdp)551 static void JNI_PeerConnection_SetLocalDescription(
552     JNIEnv* jni,
553     const JavaParamRef<jobject>& j_pc,
554     const JavaParamRef<jobject>& j_observer,
555     const JavaParamRef<jobject>& j_sdp) {
556   rtc::scoped_refptr<SetSdpObserverJni> observer(
557       new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
558   ExtractNativePC(jni, j_pc)->SetLocalDescription(
559       observer, JavaToNativeSessionDescription(jni, j_sdp).release());
560 }
561 
JNI_PeerConnection_SetRemoteDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_sdp)562 static void JNI_PeerConnection_SetRemoteDescription(
563     JNIEnv* jni,
564     const JavaParamRef<jobject>& j_pc,
565     const JavaParamRef<jobject>& j_observer,
566     const JavaParamRef<jobject>& j_sdp) {
567   rtc::scoped_refptr<SetSdpObserverJni> observer(
568       new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
569   ExtractNativePC(jni, j_pc)->SetRemoteDescription(
570       observer, JavaToNativeSessionDescription(jni, j_sdp).release());
571 }
572 
JNI_PeerConnection_SetAudioPlayout(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jboolean playout)573 static void JNI_PeerConnection_SetAudioPlayout(
574     JNIEnv* jni,
575     const JavaParamRef<jobject>& j_pc,
576     jboolean playout) {
577   ExtractNativePC(jni, j_pc)->SetAudioPlayout(playout);
578 }
579 
JNI_PeerConnection_SetAudioRecording(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jboolean recording)580 static void JNI_PeerConnection_SetAudioRecording(
581     JNIEnv* jni,
582     const JavaParamRef<jobject>& j_pc,
583     jboolean recording) {
584   ExtractNativePC(jni, j_pc)->SetAudioRecording(recording);
585 }
586 
JNI_PeerConnection_SetConfiguration(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_rtc_config)587 static jboolean JNI_PeerConnection_SetConfiguration(
588     JNIEnv* jni,
589     const JavaParamRef<jobject>& j_pc,
590     const JavaParamRef<jobject>& j_rtc_config) {
591   // Need to merge constraints into RTCConfiguration again, which are stored
592   // in the OwnedPeerConnection object.
593   OwnedPeerConnection* owned_pc = reinterpret_cast<OwnedPeerConnection*>(
594       Java_PeerConnection_getNativeOwnedPeerConnection(jni, j_pc));
595   PeerConnectionInterface::RTCConfiguration rtc_config(
596       PeerConnectionInterface::RTCConfigurationType::kAggressive);
597   JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
598   if (owned_pc->constraints()) {
599     CopyConstraintsIntoRtcConfiguration(owned_pc->constraints(), &rtc_config);
600   }
601   return owned_pc->pc()->SetConfiguration(rtc_config).ok();
602 }
603 
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)604 static jboolean JNI_PeerConnection_AddIceCandidate(
605     JNIEnv* jni,
606     const JavaParamRef<jobject>& j_pc,
607     const JavaParamRef<jstring>& j_sdp_mid,
608     jint j_sdp_mline_index,
609     const JavaParamRef<jstring>& j_candidate_sdp) {
610   std::string sdp_mid = JavaToNativeString(jni, j_sdp_mid);
611   std::string sdp = JavaToNativeString(jni, j_candidate_sdp);
612   std::unique_ptr<IceCandidateInterface> candidate(
613       CreateIceCandidate(sdp_mid, j_sdp_mline_index, sdp, nullptr));
614   return ExtractNativePC(jni, j_pc)->AddIceCandidate(candidate.get());
615 }
616 
JNI_PeerConnection_RemoveIceCandidates(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobjectArray> & j_candidates)617 static jboolean JNI_PeerConnection_RemoveIceCandidates(
618     JNIEnv* jni,
619     const JavaParamRef<jobject>& j_pc,
620     const JavaParamRef<jobjectArray>& j_candidates) {
621   std::vector<cricket::Candidate> candidates =
622       JavaToNativeVector<cricket::Candidate>(jni, j_candidates,
623                                              &JavaToNativeCandidate);
624   return ExtractNativePC(jni, j_pc)->RemoveIceCandidates(candidates);
625 }
626 
JNI_PeerConnection_AddLocalStream(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_stream)627 static jboolean JNI_PeerConnection_AddLocalStream(
628     JNIEnv* jni,
629     const JavaParamRef<jobject>& j_pc,
630     jlong native_stream) {
631   return ExtractNativePC(jni, j_pc)->AddStream(
632       reinterpret_cast<MediaStreamInterface*>(native_stream));
633 }
634 
JNI_PeerConnection_RemoveLocalStream(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_stream)635 static void JNI_PeerConnection_RemoveLocalStream(
636     JNIEnv* jni,
637     const JavaParamRef<jobject>& j_pc,
638     jlong native_stream) {
639   ExtractNativePC(jni, j_pc)->RemoveStream(
640       reinterpret_cast<MediaStreamInterface*>(native_stream));
641 }
642 
JNI_PeerConnection_CreateSender(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_kind,const JavaParamRef<jstring> & j_stream_id)643 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateSender(
644     JNIEnv* jni,
645     const JavaParamRef<jobject>& j_pc,
646     const JavaParamRef<jstring>& j_kind,
647     const JavaParamRef<jstring>& j_stream_id) {
648   std::string kind = JavaToNativeString(jni, j_kind);
649   std::string stream_id = JavaToNativeString(jni, j_stream_id);
650   rtc::scoped_refptr<RtpSenderInterface> sender =
651       ExtractNativePC(jni, j_pc)->CreateSender(kind, stream_id);
652   return NativeToJavaRtpSender(jni, sender);
653 }
654 
JNI_PeerConnection_GetSenders(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)655 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetSenders(
656     JNIEnv* jni,
657     const JavaParamRef<jobject>& j_pc) {
658   return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetSenders(),
659                           &NativeToJavaRtpSender);
660 }
661 
JNI_PeerConnection_GetReceivers(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)662 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetReceivers(
663     JNIEnv* jni,
664     const JavaParamRef<jobject>& j_pc) {
665   return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetReceivers(),
666                           &NativeToJavaRtpReceiver);
667 }
668 
JNI_PeerConnection_GetTransceivers(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)669 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetTransceivers(
670     JNIEnv* jni,
671     const JavaParamRef<jobject>& j_pc) {
672   return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetTransceivers(),
673                           &NativeToJavaRtpTransceiver);
674 }
675 
JNI_PeerConnection_AddTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const jlong native_track,const JavaParamRef<jobject> & j_stream_labels)676 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTrack(
677     JNIEnv* jni,
678     const JavaParamRef<jobject>& j_pc,
679     const jlong native_track,
680     const JavaParamRef<jobject>& j_stream_labels) {
681   RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
682       ExtractNativePC(jni, j_pc)->AddTrack(
683           reinterpret_cast<MediaStreamTrackInterface*>(native_track),
684           JavaListToNativeVector<std::string, jstring>(jni, j_stream_labels,
685                                                        &JavaToNativeString));
686   if (!result.ok()) {
687     RTC_LOG(LS_ERROR) << "Failed to add track: " << result.error().message();
688     return nullptr;
689   } else {
690     return NativeToJavaRtpSender(jni, result.MoveValue());
691   }
692 }
693 
JNI_PeerConnection_RemoveTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_sender)694 static jboolean JNI_PeerConnection_RemoveTrack(
695     JNIEnv* jni,
696     const JavaParamRef<jobject>& j_pc,
697     jlong native_sender) {
698   return ExtractNativePC(jni, j_pc)->RemoveTrack(
699       reinterpret_cast<RtpSenderInterface*>(native_sender));
700 }
701 
JNI_PeerConnection_AddTransceiverWithTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_track,const JavaParamRef<jobject> & j_init)702 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTransceiverWithTrack(
703     JNIEnv* jni,
704     const JavaParamRef<jobject>& j_pc,
705     jlong native_track,
706     const JavaParamRef<jobject>& j_init) {
707   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
708       ExtractNativePC(jni, j_pc)->AddTransceiver(
709           reinterpret_cast<MediaStreamTrackInterface*>(native_track),
710           JavaToNativeRtpTransceiverInit(jni, j_init));
711   if (!result.ok()) {
712     RTC_LOG(LS_ERROR) << "Failed to add transceiver: "
713                       << result.error().message();
714     return nullptr;
715   } else {
716     return NativeToJavaRtpTransceiver(jni, result.MoveValue());
717   }
718 }
719 
JNI_PeerConnection_AddTransceiverOfType(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_media_type,const JavaParamRef<jobject> & j_init)720 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTransceiverOfType(
721     JNIEnv* jni,
722     const JavaParamRef<jobject>& j_pc,
723     const JavaParamRef<jobject>& j_media_type,
724     const JavaParamRef<jobject>& j_init) {
725   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
726       ExtractNativePC(jni, j_pc)->AddTransceiver(
727           JavaToNativeMediaType(jni, j_media_type),
728           JavaToNativeRtpTransceiverInit(jni, j_init));
729   if (!result.ok()) {
730     RTC_LOG(LS_ERROR) << "Failed to add transceiver: "
731                       << result.error().message();
732     return nullptr;
733   } else {
734     return NativeToJavaRtpTransceiver(jni, result.MoveValue());
735   }
736 }
737 
JNI_PeerConnection_OldGetStats(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,jlong native_track)738 static jboolean JNI_PeerConnection_OldGetStats(
739     JNIEnv* jni,
740     const JavaParamRef<jobject>& j_pc,
741     const JavaParamRef<jobject>& j_observer,
742     jlong native_track) {
743   rtc::scoped_refptr<StatsObserverJni> observer(
744       new rtc::RefCountedObject<StatsObserverJni>(jni, j_observer));
745   return ExtractNativePC(jni, j_pc)->GetStats(
746       observer, reinterpret_cast<MediaStreamTrackInterface*>(native_track),
747       PeerConnectionInterface::kStatsOutputLevelStandard);
748 }
749 
JNI_PeerConnection_NewGetStats(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_callback)750 static void JNI_PeerConnection_NewGetStats(
751     JNIEnv* jni,
752     const JavaParamRef<jobject>& j_pc,
753     const JavaParamRef<jobject>& j_callback) {
754   rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper> callback(
755       new rtc::RefCountedObject<RTCStatsCollectorCallbackWrapper>(jni,
756                                                                   j_callback));
757   ExtractNativePC(jni, j_pc)->GetStats(callback);
758 }
759 
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)760 static jboolean JNI_PeerConnection_SetBitrate(
761     JNIEnv* jni,
762     const JavaParamRef<jobject>& j_pc,
763     const JavaParamRef<jobject>& j_min,
764     const JavaParamRef<jobject>& j_current,
765     const JavaParamRef<jobject>& j_max) {
766   PeerConnectionInterface::BitrateParameters params;
767   params.min_bitrate_bps = JavaToNativeOptionalInt(jni, j_min);
768   params.current_bitrate_bps = JavaToNativeOptionalInt(jni, j_current);
769   params.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_max);
770   return ExtractNativePC(jni, j_pc)->SetBitrate(params).ok();
771 }
772 
JNI_PeerConnection_StartRtcEventLog(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,int file_descriptor,int max_size_bytes)773 static jboolean JNI_PeerConnection_StartRtcEventLog(
774     JNIEnv* jni,
775     const JavaParamRef<jobject>& j_pc,
776     int file_descriptor,
777     int max_size_bytes) {
778   // TODO(eladalon): It would be better to not allow negative values into PC.
779   const size_t max_size = (max_size_bytes < 0)
780                               ? RtcEventLog::kUnlimitedOutput
781                               : rtc::saturated_cast<size_t>(max_size_bytes);
782   FILE* f = fdopen(file_descriptor, "wb");
783   if (!f) {
784     close(file_descriptor);
785     return false;
786   }
787   return ExtractNativePC(jni, j_pc)->StartRtcEventLog(
788       std::make_unique<RtcEventLogOutputFile>(f, max_size));
789 }
790 
JNI_PeerConnection_StopRtcEventLog(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)791 static void JNI_PeerConnection_StopRtcEventLog(
792     JNIEnv* jni,
793     const JavaParamRef<jobject>& j_pc) {
794   ExtractNativePC(jni, j_pc)->StopRtcEventLog();
795 }
796 
JNI_PeerConnection_SignalingState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)797 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_SignalingState(
798     JNIEnv* env,
799     const JavaParamRef<jobject>& j_pc) {
800   return Java_SignalingState_fromNativeIndex(
801       env, ExtractNativePC(env, j_pc)->signaling_state());
802 }
803 
JNI_PeerConnection_IceConnectionState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)804 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceConnectionState(
805     JNIEnv* env,
806     const JavaParamRef<jobject>& j_pc) {
807   return Java_IceConnectionState_fromNativeIndex(
808       env, ExtractNativePC(env, j_pc)->ice_connection_state());
809 }
810 
JNI_PeerConnection_ConnectionState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)811 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_ConnectionState(
812     JNIEnv* env,
813     const JavaParamRef<jobject>& j_pc) {
814   return Java_PeerConnectionState_fromNativeIndex(
815       env,
816       static_cast<int>(ExtractNativePC(env, j_pc)->peer_connection_state()));
817 }
818 
JNI_PeerConnection_IceGatheringState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)819 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceGatheringState(
820     JNIEnv* env,
821     const JavaParamRef<jobject>& j_pc) {
822   return Java_IceGatheringState_fromNativeIndex(
823       env, ExtractNativePC(env, j_pc)->ice_gathering_state());
824 }
825 
JNI_PeerConnection_Close(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)826 static void JNI_PeerConnection_Close(JNIEnv* jni,
827                                      const JavaParamRef<jobject>& j_pc) {
828   ExtractNativePC(jni, j_pc)->Close();
829 }
830 
831 }  // namespace jni
832 }  // namespace webrtc
833