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->crypto_options =
268 JavaToNativeOptionalCryptoOptions(jni, j_crypto_options);
269
270 rtc_config->allow_codec_switching = JavaToNativeOptionalBool(
271 jni, Java_RTCConfiguration_getAllowCodecSwitching(jni, j_rtc_config));
272
273 ScopedJavaLocalRef<jstring> j_turn_logging_id =
274 Java_RTCConfiguration_getTurnLoggingId(jni, j_rtc_config);
275 if (!IsNull(jni, j_turn_logging_id)) {
276 rtc_config->turn_logging_id = JavaToNativeString(jni, j_turn_logging_id);
277 }
278 }
279
GetRtcConfigKeyType(JNIEnv * env,const JavaRef<jobject> & j_rtc_config)280 rtc::KeyType GetRtcConfigKeyType(JNIEnv* env,
281 const JavaRef<jobject>& j_rtc_config) {
282 return JavaToNativeKeyType(
283 env, Java_RTCConfiguration_getKeyType(env, j_rtc_config));
284 }
285
PeerConnectionObserverJni(JNIEnv * jni,const JavaRef<jobject> & j_observer)286 PeerConnectionObserverJni::PeerConnectionObserverJni(
287 JNIEnv* jni,
288 const JavaRef<jobject>& j_observer)
289 : j_observer_global_(jni, j_observer) {}
290
291 PeerConnectionObserverJni::~PeerConnectionObserverJni() = default;
292
OnIceCandidate(const IceCandidateInterface * candidate)293 void PeerConnectionObserverJni::OnIceCandidate(
294 const IceCandidateInterface* candidate) {
295 JNIEnv* env = AttachCurrentThreadIfNeeded();
296 Java_Observer_onIceCandidate(env, j_observer_global_,
297 NativeToJavaIceCandidate(env, *candidate));
298 }
299
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)300 void PeerConnectionObserverJni::OnIceCandidatesRemoved(
301 const std::vector<cricket::Candidate>& candidates) {
302 JNIEnv* env = AttachCurrentThreadIfNeeded();
303 Java_Observer_onIceCandidatesRemoved(
304 env, j_observer_global_, NativeToJavaCandidateArray(env, candidates));
305 }
306
OnSignalingChange(PeerConnectionInterface::SignalingState new_state)307 void PeerConnectionObserverJni::OnSignalingChange(
308 PeerConnectionInterface::SignalingState new_state) {
309 JNIEnv* env = AttachCurrentThreadIfNeeded();
310 Java_Observer_onSignalingChange(
311 env, j_observer_global_,
312 Java_SignalingState_fromNativeIndex(env, new_state));
313 }
314
OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)315 void PeerConnectionObserverJni::OnIceConnectionChange(
316 PeerConnectionInterface::IceConnectionState new_state) {
317 JNIEnv* env = AttachCurrentThreadIfNeeded();
318 Java_Observer_onIceConnectionChange(
319 env, j_observer_global_,
320 Java_IceConnectionState_fromNativeIndex(env, new_state));
321 }
322
OnStandardizedIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)323 void PeerConnectionObserverJni::OnStandardizedIceConnectionChange(
324 PeerConnectionInterface::IceConnectionState new_state) {
325 JNIEnv* env = AttachCurrentThreadIfNeeded();
326 Java_Observer_onStandardizedIceConnectionChange(
327 env, j_observer_global_,
328 Java_IceConnectionState_fromNativeIndex(env, new_state));
329 }
330
OnConnectionChange(PeerConnectionInterface::PeerConnectionState new_state)331 void PeerConnectionObserverJni::OnConnectionChange(
332 PeerConnectionInterface::PeerConnectionState new_state) {
333 JNIEnv* env = AttachCurrentThreadIfNeeded();
334 Java_Observer_onConnectionChange(env, j_observer_global_,
335 Java_PeerConnectionState_fromNativeIndex(
336 env, static_cast<int>(new_state)));
337 }
338
OnIceConnectionReceivingChange(bool receiving)339 void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) {
340 JNIEnv* env = AttachCurrentThreadIfNeeded();
341 Java_Observer_onIceConnectionReceivingChange(env, j_observer_global_,
342 receiving);
343 }
344
OnIceSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent & event)345 void PeerConnectionObserverJni::OnIceSelectedCandidatePairChanged(
346 const cricket::CandidatePairChangeEvent& event) {
347 JNIEnv* env = AttachCurrentThreadIfNeeded();
348 Java_Observer_onSelectedCandidatePairChanged(
349 env, j_observer_global_, NativeToJavaCandidatePairChange(env, event));
350 }
351
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)352 void PeerConnectionObserverJni::OnIceGatheringChange(
353 PeerConnectionInterface::IceGatheringState new_state) {
354 JNIEnv* env = AttachCurrentThreadIfNeeded();
355 Java_Observer_onIceGatheringChange(
356 env, j_observer_global_,
357 Java_IceGatheringState_fromNativeIndex(env, new_state));
358 }
359
OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream)360 void PeerConnectionObserverJni::OnAddStream(
361 rtc::scoped_refptr<MediaStreamInterface> stream) {
362 JNIEnv* env = AttachCurrentThreadIfNeeded();
363 Java_Observer_onAddStream(
364 env, j_observer_global_,
365 GetOrCreateJavaStream(env, stream).j_media_stream());
366 }
367
OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream)368 void PeerConnectionObserverJni::OnRemoveStream(
369 rtc::scoped_refptr<MediaStreamInterface> stream) {
370 JNIEnv* env = AttachCurrentThreadIfNeeded();
371 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
372 RTC_CHECK(it != remote_streams_.end()) << "unexpected stream: " << stream;
373 Java_Observer_onRemoveStream(env, j_observer_global_,
374 it->second.j_media_stream());
375 remote_streams_.erase(it);
376 }
377
OnDataChannel(rtc::scoped_refptr<DataChannelInterface> channel)378 void PeerConnectionObserverJni::OnDataChannel(
379 rtc::scoped_refptr<DataChannelInterface> channel) {
380 JNIEnv* env = AttachCurrentThreadIfNeeded();
381 Java_Observer_onDataChannel(env, j_observer_global_,
382 WrapNativeDataChannel(env, channel));
383 }
384
OnRenegotiationNeeded()385 void PeerConnectionObserverJni::OnRenegotiationNeeded() {
386 JNIEnv* env = AttachCurrentThreadIfNeeded();
387 Java_Observer_onRenegotiationNeeded(env, j_observer_global_);
388 }
389
OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)390 void PeerConnectionObserverJni::OnAddTrack(
391 rtc::scoped_refptr<RtpReceiverInterface> receiver,
392 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
393 JNIEnv* env = AttachCurrentThreadIfNeeded();
394 ScopedJavaLocalRef<jobject> j_rtp_receiver =
395 NativeToJavaRtpReceiver(env, receiver);
396 rtp_receivers_.emplace_back(env, j_rtp_receiver);
397
398 Java_Observer_onAddTrack(env, j_observer_global_, j_rtp_receiver,
399 NativeToJavaMediaStreamArray(env, streams));
400 }
401
OnTrack(rtc::scoped_refptr<RtpTransceiverInterface> transceiver)402 void PeerConnectionObserverJni::OnTrack(
403 rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
404 JNIEnv* env = AttachCurrentThreadIfNeeded();
405 ScopedJavaLocalRef<jobject> j_rtp_transceiver =
406 NativeToJavaRtpTransceiver(env, transceiver);
407 rtp_transceivers_.emplace_back(env, j_rtp_transceiver);
408
409 Java_Observer_onTrack(env, j_observer_global_, j_rtp_transceiver);
410 }
411
412 // If the NativeToJavaStreamsMap contains the stream, return it.
413 // Otherwise, create a new Java MediaStream.
GetOrCreateJavaStream(JNIEnv * env,const rtc::scoped_refptr<MediaStreamInterface> & stream)414 JavaMediaStream& PeerConnectionObserverJni::GetOrCreateJavaStream(
415 JNIEnv* env,
416 const rtc::scoped_refptr<MediaStreamInterface>& stream) {
417 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
418 if (it == remote_streams_.end()) {
419 it = remote_streams_
420 .emplace(std::piecewise_construct,
421 std::forward_as_tuple(stream.get()),
422 std::forward_as_tuple(env, stream))
423 .first;
424 }
425 return it->second;
426 }
427
428 ScopedJavaLocalRef<jobjectArray>
NativeToJavaMediaStreamArray(JNIEnv * jni,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)429 PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
430 JNIEnv* jni,
431 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
432 return NativeToJavaObjectArray(
433 jni, streams, GetMediaStreamClass(jni),
434 [this](JNIEnv* env, rtc::scoped_refptr<MediaStreamInterface> stream)
435 -> const ScopedJavaGlobalRef<jobject>& {
436 return GetOrCreateJavaStream(env, stream).j_media_stream();
437 });
438 }
439
OwnedPeerConnection(rtc::scoped_refptr<PeerConnectionInterface> peer_connection,std::unique_ptr<PeerConnectionObserver> observer)440 OwnedPeerConnection::OwnedPeerConnection(
441 rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
442 std::unique_ptr<PeerConnectionObserver> observer)
443 : OwnedPeerConnection(peer_connection,
444 std::move(observer),
445 nullptr /* constraints */) {}
446
OwnedPeerConnection(rtc::scoped_refptr<PeerConnectionInterface> peer_connection,std::unique_ptr<PeerConnectionObserver> observer,std::unique_ptr<MediaConstraints> constraints)447 OwnedPeerConnection::OwnedPeerConnection(
448 rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
449 std::unique_ptr<PeerConnectionObserver> observer,
450 std::unique_ptr<MediaConstraints> constraints)
451 : peer_connection_(peer_connection),
452 observer_(std::move(observer)),
453 constraints_(std::move(constraints)) {}
454
~OwnedPeerConnection()455 OwnedPeerConnection::~OwnedPeerConnection() {
456 // Ensure that PeerConnection is destroyed before the observer.
457 peer_connection_ = nullptr;
458 }
459
JNI_PeerConnection_CreatePeerConnectionObserver(JNIEnv * jni,const JavaParamRef<jobject> & j_observer)460 static jlong JNI_PeerConnection_CreatePeerConnectionObserver(
461 JNIEnv* jni,
462 const JavaParamRef<jobject>& j_observer) {
463 return jlongFromPointer(new PeerConnectionObserverJni(jni, j_observer));
464 }
465
JNI_PeerConnection_FreeOwnedPeerConnection(JNIEnv *,jlong j_p)466 static void JNI_PeerConnection_FreeOwnedPeerConnection(
467 JNIEnv*,
468 jlong j_p) {
469 delete reinterpret_cast<OwnedPeerConnection*>(j_p);
470 }
471
JNI_PeerConnection_GetNativePeerConnection(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)472 static jlong JNI_PeerConnection_GetNativePeerConnection(
473 JNIEnv* jni,
474 const JavaParamRef<jobject>& j_pc) {
475 return jlongFromPointer(ExtractNativePC(jni, j_pc));
476 }
477
JNI_PeerConnection_GetLocalDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)478 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetLocalDescription(
479 JNIEnv* jni,
480 const JavaParamRef<jobject>& j_pc) {
481 const SessionDescriptionInterface* sdp =
482 ExtractNativePC(jni, j_pc)->local_description();
483 return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
484 }
485
JNI_PeerConnection_GetRemoteDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)486 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetRemoteDescription(
487 JNIEnv* jni,
488 const JavaParamRef<jobject>& j_pc) {
489 const SessionDescriptionInterface* sdp =
490 ExtractNativePC(jni, j_pc)->remote_description();
491 return sdp ? NativeToJavaSessionDescription(jni, sdp) : nullptr;
492 }
493
JNI_PeerConnection_GetCertificate(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)494 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetCertificate(
495 JNIEnv* jni,
496 const JavaParamRef<jobject>& j_pc) {
497 const PeerConnectionInterface::RTCConfiguration rtc_config =
498 ExtractNativePC(jni, j_pc)->GetConfiguration();
499 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
500 rtc_config.certificates[0];
501 return NativeToJavaRTCCertificatePEM(jni, certificate->ToPEM());
502 }
503
JNI_PeerConnection_CreateDataChannel(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_label,const JavaParamRef<jobject> & j_init)504 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateDataChannel(
505 JNIEnv* jni,
506 const JavaParamRef<jobject>& j_pc,
507 const JavaParamRef<jstring>& j_label,
508 const JavaParamRef<jobject>& j_init) {
509 DataChannelInit init = JavaToNativeDataChannelInit(jni, j_init);
510 rtc::scoped_refptr<DataChannelInterface> channel(
511 ExtractNativePC(jni, j_pc)->CreateDataChannel(
512 JavaToNativeString(jni, j_label), &init));
513 return WrapNativeDataChannel(jni, channel);
514 }
515
JNI_PeerConnection_CreateOffer(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_constraints)516 static void JNI_PeerConnection_CreateOffer(
517 JNIEnv* jni,
518 const JavaParamRef<jobject>& j_pc,
519 const JavaParamRef<jobject>& j_observer,
520 const JavaParamRef<jobject>& j_constraints) {
521 std::unique_ptr<MediaConstraints> constraints =
522 JavaToNativeMediaConstraints(jni, j_constraints);
523 rtc::scoped_refptr<CreateSdpObserverJni> observer(
524 new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
525 std::move(constraints)));
526 PeerConnectionInterface::RTCOfferAnswerOptions options;
527 CopyConstraintsIntoOfferAnswerOptions(observer->constraints(), &options);
528 ExtractNativePC(jni, j_pc)->CreateOffer(observer, options);
529 }
530
JNI_PeerConnection_CreateAnswer(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_constraints)531 static void JNI_PeerConnection_CreateAnswer(
532 JNIEnv* jni,
533 const JavaParamRef<jobject>& j_pc,
534 const JavaParamRef<jobject>& j_observer,
535 const JavaParamRef<jobject>& j_constraints) {
536 std::unique_ptr<MediaConstraints> constraints =
537 JavaToNativeMediaConstraints(jni, j_constraints);
538 rtc::scoped_refptr<CreateSdpObserverJni> observer(
539 new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
540 std::move(constraints)));
541 PeerConnectionInterface::RTCOfferAnswerOptions options;
542 CopyConstraintsIntoOfferAnswerOptions(observer->constraints(), &options);
543 ExtractNativePC(jni, j_pc)->CreateAnswer(observer, options);
544 }
545
JNI_PeerConnection_SetLocalDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_sdp)546 static void JNI_PeerConnection_SetLocalDescription(
547 JNIEnv* jni,
548 const JavaParamRef<jobject>& j_pc,
549 const JavaParamRef<jobject>& j_observer,
550 const JavaParamRef<jobject>& j_sdp) {
551 rtc::scoped_refptr<SetSdpObserverJni> observer(
552 new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
553 ExtractNativePC(jni, j_pc)->SetLocalDescription(
554 observer, JavaToNativeSessionDescription(jni, j_sdp).release());
555 }
556
JNI_PeerConnection_SetRemoteDescription(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,const JavaParamRef<jobject> & j_sdp)557 static void JNI_PeerConnection_SetRemoteDescription(
558 JNIEnv* jni,
559 const JavaParamRef<jobject>& j_pc,
560 const JavaParamRef<jobject>& j_observer,
561 const JavaParamRef<jobject>& j_sdp) {
562 rtc::scoped_refptr<SetSdpObserverJni> observer(
563 new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
564 ExtractNativePC(jni, j_pc)->SetRemoteDescription(
565 observer, JavaToNativeSessionDescription(jni, j_sdp).release());
566 }
567
JNI_PeerConnection_SetAudioPlayout(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jboolean playout)568 static void JNI_PeerConnection_SetAudioPlayout(
569 JNIEnv* jni,
570 const JavaParamRef<jobject>& j_pc,
571 jboolean playout) {
572 ExtractNativePC(jni, j_pc)->SetAudioPlayout(playout);
573 }
574
JNI_PeerConnection_SetAudioRecording(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jboolean recording)575 static void JNI_PeerConnection_SetAudioRecording(
576 JNIEnv* jni,
577 const JavaParamRef<jobject>& j_pc,
578 jboolean recording) {
579 ExtractNativePC(jni, j_pc)->SetAudioRecording(recording);
580 }
581
JNI_PeerConnection_SetConfiguration(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_rtc_config)582 static jboolean JNI_PeerConnection_SetConfiguration(
583 JNIEnv* jni,
584 const JavaParamRef<jobject>& j_pc,
585 const JavaParamRef<jobject>& j_rtc_config) {
586 // Need to merge constraints into RTCConfiguration again, which are stored
587 // in the OwnedPeerConnection object.
588 OwnedPeerConnection* owned_pc = reinterpret_cast<OwnedPeerConnection*>(
589 Java_PeerConnection_getNativeOwnedPeerConnection(jni, j_pc));
590 PeerConnectionInterface::RTCConfiguration rtc_config(
591 PeerConnectionInterface::RTCConfigurationType::kAggressive);
592 JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
593 if (owned_pc->constraints()) {
594 CopyConstraintsIntoRtcConfiguration(owned_pc->constraints(), &rtc_config);
595 }
596 return owned_pc->pc()->SetConfiguration(rtc_config).ok();
597 }
598
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)599 static jboolean JNI_PeerConnection_AddIceCandidate(
600 JNIEnv* jni,
601 const JavaParamRef<jobject>& j_pc,
602 const JavaParamRef<jstring>& j_sdp_mid,
603 jint j_sdp_mline_index,
604 const JavaParamRef<jstring>& j_candidate_sdp) {
605 std::string sdp_mid = JavaToNativeString(jni, j_sdp_mid);
606 std::string sdp = JavaToNativeString(jni, j_candidate_sdp);
607 std::unique_ptr<IceCandidateInterface> candidate(
608 CreateIceCandidate(sdp_mid, j_sdp_mline_index, sdp, nullptr));
609 return ExtractNativePC(jni, j_pc)->AddIceCandidate(candidate.get());
610 }
611
JNI_PeerConnection_RemoveIceCandidates(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobjectArray> & j_candidates)612 static jboolean JNI_PeerConnection_RemoveIceCandidates(
613 JNIEnv* jni,
614 const JavaParamRef<jobject>& j_pc,
615 const JavaParamRef<jobjectArray>& j_candidates) {
616 std::vector<cricket::Candidate> candidates =
617 JavaToNativeVector<cricket::Candidate>(jni, j_candidates,
618 &JavaToNativeCandidate);
619 return ExtractNativePC(jni, j_pc)->RemoveIceCandidates(candidates);
620 }
621
JNI_PeerConnection_AddLocalStream(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_stream)622 static jboolean JNI_PeerConnection_AddLocalStream(
623 JNIEnv* jni,
624 const JavaParamRef<jobject>& j_pc,
625 jlong native_stream) {
626 return ExtractNativePC(jni, j_pc)->AddStream(
627 reinterpret_cast<MediaStreamInterface*>(native_stream));
628 }
629
JNI_PeerConnection_RemoveLocalStream(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_stream)630 static void JNI_PeerConnection_RemoveLocalStream(
631 JNIEnv* jni,
632 const JavaParamRef<jobject>& j_pc,
633 jlong native_stream) {
634 ExtractNativePC(jni, j_pc)->RemoveStream(
635 reinterpret_cast<MediaStreamInterface*>(native_stream));
636 }
637
JNI_PeerConnection_CreateSender(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jstring> & j_kind,const JavaParamRef<jstring> & j_stream_id)638 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_CreateSender(
639 JNIEnv* jni,
640 const JavaParamRef<jobject>& j_pc,
641 const JavaParamRef<jstring>& j_kind,
642 const JavaParamRef<jstring>& j_stream_id) {
643 std::string kind = JavaToNativeString(jni, j_kind);
644 std::string stream_id = JavaToNativeString(jni, j_stream_id);
645 rtc::scoped_refptr<RtpSenderInterface> sender =
646 ExtractNativePC(jni, j_pc)->CreateSender(kind, stream_id);
647 return NativeToJavaRtpSender(jni, sender);
648 }
649
JNI_PeerConnection_GetSenders(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)650 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetSenders(
651 JNIEnv* jni,
652 const JavaParamRef<jobject>& j_pc) {
653 return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetSenders(),
654 &NativeToJavaRtpSender);
655 }
656
JNI_PeerConnection_GetReceivers(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)657 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetReceivers(
658 JNIEnv* jni,
659 const JavaParamRef<jobject>& j_pc) {
660 return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetReceivers(),
661 &NativeToJavaRtpReceiver);
662 }
663
JNI_PeerConnection_GetTransceivers(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)664 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_GetTransceivers(
665 JNIEnv* jni,
666 const JavaParamRef<jobject>& j_pc) {
667 return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetTransceivers(),
668 &NativeToJavaRtpTransceiver);
669 }
670
JNI_PeerConnection_AddTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const jlong native_track,const JavaParamRef<jobject> & j_stream_labels)671 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTrack(
672 JNIEnv* jni,
673 const JavaParamRef<jobject>& j_pc,
674 const jlong native_track,
675 const JavaParamRef<jobject>& j_stream_labels) {
676 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
677 ExtractNativePC(jni, j_pc)->AddTrack(
678 reinterpret_cast<MediaStreamTrackInterface*>(native_track),
679 JavaListToNativeVector<std::string, jstring>(jni, j_stream_labels,
680 &JavaToNativeString));
681 if (!result.ok()) {
682 RTC_LOG(LS_ERROR) << "Failed to add track: " << result.error().message();
683 return nullptr;
684 } else {
685 return NativeToJavaRtpSender(jni, result.MoveValue());
686 }
687 }
688
JNI_PeerConnection_RemoveTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_sender)689 static jboolean JNI_PeerConnection_RemoveTrack(
690 JNIEnv* jni,
691 const JavaParamRef<jobject>& j_pc,
692 jlong native_sender) {
693 return ExtractNativePC(jni, j_pc)->RemoveTrack(
694 reinterpret_cast<RtpSenderInterface*>(native_sender));
695 }
696
JNI_PeerConnection_AddTransceiverWithTrack(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,jlong native_track,const JavaParamRef<jobject> & j_init)697 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTransceiverWithTrack(
698 JNIEnv* jni,
699 const JavaParamRef<jobject>& j_pc,
700 jlong native_track,
701 const JavaParamRef<jobject>& j_init) {
702 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
703 ExtractNativePC(jni, j_pc)->AddTransceiver(
704 reinterpret_cast<MediaStreamTrackInterface*>(native_track),
705 JavaToNativeRtpTransceiverInit(jni, j_init));
706 if (!result.ok()) {
707 RTC_LOG(LS_ERROR) << "Failed to add transceiver: "
708 << result.error().message();
709 return nullptr;
710 } else {
711 return NativeToJavaRtpTransceiver(jni, result.MoveValue());
712 }
713 }
714
JNI_PeerConnection_AddTransceiverOfType(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_media_type,const JavaParamRef<jobject> & j_init)715 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_AddTransceiverOfType(
716 JNIEnv* jni,
717 const JavaParamRef<jobject>& j_pc,
718 const JavaParamRef<jobject>& j_media_type,
719 const JavaParamRef<jobject>& j_init) {
720 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
721 ExtractNativePC(jni, j_pc)->AddTransceiver(
722 JavaToNativeMediaType(jni, j_media_type),
723 JavaToNativeRtpTransceiverInit(jni, j_init));
724 if (!result.ok()) {
725 RTC_LOG(LS_ERROR) << "Failed to add transceiver: "
726 << result.error().message();
727 return nullptr;
728 } else {
729 return NativeToJavaRtpTransceiver(jni, result.MoveValue());
730 }
731 }
732
JNI_PeerConnection_OldGetStats(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_observer,jlong native_track)733 static jboolean JNI_PeerConnection_OldGetStats(
734 JNIEnv* jni,
735 const JavaParamRef<jobject>& j_pc,
736 const JavaParamRef<jobject>& j_observer,
737 jlong native_track) {
738 rtc::scoped_refptr<StatsObserverJni> observer(
739 new rtc::RefCountedObject<StatsObserverJni>(jni, j_observer));
740 return ExtractNativePC(jni, j_pc)->GetStats(
741 observer, reinterpret_cast<MediaStreamTrackInterface*>(native_track),
742 PeerConnectionInterface::kStatsOutputLevelStandard);
743 }
744
JNI_PeerConnection_NewGetStats(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,const JavaParamRef<jobject> & j_callback)745 static void JNI_PeerConnection_NewGetStats(
746 JNIEnv* jni,
747 const JavaParamRef<jobject>& j_pc,
748 const JavaParamRef<jobject>& j_callback) {
749 rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper> callback(
750 new rtc::RefCountedObject<RTCStatsCollectorCallbackWrapper>(jni,
751 j_callback));
752 ExtractNativePC(jni, j_pc)->GetStats(callback);
753 }
754
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)755 static jboolean JNI_PeerConnection_SetBitrate(
756 JNIEnv* jni,
757 const JavaParamRef<jobject>& j_pc,
758 const JavaParamRef<jobject>& j_min,
759 const JavaParamRef<jobject>& j_current,
760 const JavaParamRef<jobject>& j_max) {
761 BitrateSettings params;
762 params.min_bitrate_bps = JavaToNativeOptionalInt(jni, j_min);
763 params.start_bitrate_bps = JavaToNativeOptionalInt(jni, j_current);
764 params.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_max);
765 return ExtractNativePC(jni, j_pc)->SetBitrate(params).ok();
766 }
767
JNI_PeerConnection_StartRtcEventLog(JNIEnv * jni,const JavaParamRef<jobject> & j_pc,int file_descriptor,int max_size_bytes)768 static jboolean JNI_PeerConnection_StartRtcEventLog(
769 JNIEnv* jni,
770 const JavaParamRef<jobject>& j_pc,
771 int file_descriptor,
772 int max_size_bytes) {
773 // TODO(eladalon): It would be better to not allow negative values into PC.
774 const size_t max_size = (max_size_bytes < 0)
775 ? RtcEventLog::kUnlimitedOutput
776 : rtc::saturated_cast<size_t>(max_size_bytes);
777 FILE* f = fdopen(file_descriptor, "wb");
778 if (!f) {
779 close(file_descriptor);
780 return false;
781 }
782 return ExtractNativePC(jni, j_pc)->StartRtcEventLog(
783 std::make_unique<RtcEventLogOutputFile>(f, max_size));
784 }
785
JNI_PeerConnection_StopRtcEventLog(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)786 static void JNI_PeerConnection_StopRtcEventLog(
787 JNIEnv* jni,
788 const JavaParamRef<jobject>& j_pc) {
789 ExtractNativePC(jni, j_pc)->StopRtcEventLog();
790 }
791
JNI_PeerConnection_SignalingState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)792 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_SignalingState(
793 JNIEnv* env,
794 const JavaParamRef<jobject>& j_pc) {
795 return Java_SignalingState_fromNativeIndex(
796 env, ExtractNativePC(env, j_pc)->signaling_state());
797 }
798
JNI_PeerConnection_IceConnectionState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)799 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceConnectionState(
800 JNIEnv* env,
801 const JavaParamRef<jobject>& j_pc) {
802 return Java_IceConnectionState_fromNativeIndex(
803 env, ExtractNativePC(env, j_pc)->ice_connection_state());
804 }
805
JNI_PeerConnection_ConnectionState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)806 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_ConnectionState(
807 JNIEnv* env,
808 const JavaParamRef<jobject>& j_pc) {
809 return Java_PeerConnectionState_fromNativeIndex(
810 env,
811 static_cast<int>(ExtractNativePC(env, j_pc)->peer_connection_state()));
812 }
813
JNI_PeerConnection_IceGatheringState(JNIEnv * env,const JavaParamRef<jobject> & j_pc)814 static ScopedJavaLocalRef<jobject> JNI_PeerConnection_IceGatheringState(
815 JNIEnv* env,
816 const JavaParamRef<jobject>& j_pc) {
817 return Java_IceGatheringState_fromNativeIndex(
818 env, ExtractNativePC(env, j_pc)->ice_gathering_state());
819 }
820
JNI_PeerConnection_Close(JNIEnv * jni,const JavaParamRef<jobject> & j_pc)821 static void JNI_PeerConnection_Close(JNIEnv* jni,
822 const JavaParamRef<jobject>& j_pc) {
823 ExtractNativePC(jni, j_pc)->Close();
824 }
825
826 } // namespace jni
827 } // namespace webrtc
828