Implement JNI and objc implementation for Ice Candidate Pair Change event surfacing

Bug: webrtc:10419
Change-Id: I18528bf2526e933568bf052de76a434f012161da
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148320
Commit-Queue: Alex Drake <alexdrake@google.com>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Reviewed-by: Alex Glaznev <glaznev@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28838}
This commit is contained in:
Alex Drake
2019-08-12 16:27:34 -07:00
committed by Commit Bot
parent 519fc4454a
commit 43faee09e5
12 changed files with 116 additions and 9 deletions

View File

@ -40,6 +40,7 @@ import org.appspot.apprtc.RecordedAudioToFileController;
import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.CameraVideoCapturer;
import org.webrtc.CandidatePairChangeEvent;
import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
@ -1214,6 +1215,11 @@ public class PeerConnectionClient {
Log.d(TAG, "IceConnectionReceiving changed to " + receiving);
}
@Override
public void onSelectedCandidatePairChanged(CandidatePairChangeEvent event) {
Log.d(TAG, "Selected candidate pair changed because: " + event);
}
@Override
public void onAddStream(final MediaStream stream) {}

View File

@ -433,6 +433,14 @@ static int const kKbpsMultiplier = 1000;
});
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didChangeLocalCandidate:(RTCIceCandidate *)local
didChangeRemoteCandidate:(RTCIceCandidate *)remote
lastReceivedMs:(int)lastDataReceivedMs
didHaveReason:(NSString *)reason {
RTCLog(@"ICE candidate pair changed because: %@", reason);
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didOpenDataChannel:(RTCDataChannel *)dataChannel {
}

View File

@ -940,6 +940,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
const cricket::CandidatePairChangeEvent& event) {
ice_candidate_pair_change_history_.push_back(event);
}
void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";

View File

@ -266,6 +266,7 @@ if (is_android) {
"api/org/webrtc/AudioSource.java",
"api/org/webrtc/AudioTrack.java",
"api/org/webrtc/CallSessionFileRotatingLogSink.java",
"api/org/webrtc/CandidatePairChangeEvent.java",
"api/org/webrtc/CryptoOptions.java",
"api/org/webrtc/DataChannel.java",
"api/org/webrtc/DtmfSender.java",
@ -1263,6 +1264,7 @@ if (current_os == "linux" || is_android) {
sources = [
"api/org/webrtc/AudioTrack.java",
"api/org/webrtc/CallSessionFileRotatingLogSink.java",
"api/org/webrtc/CandidatePairChangeEvent.java",
"api/org/webrtc/CryptoOptions.java",
"api/org/webrtc/DataChannel.java",
"api/org/webrtc/DtmfSender.java",

View File

@ -0,0 +1,31 @@
/*
* Copyright 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc;
/**
* Representation of a change in selected ICE candidate pair.
* {@code CandidatePairChangeEvent} in the C++ API.
*/
public final class CandidatePairChangeEvent {
public final IceCandidate local;
public final IceCandidate remote;
public final int lastDataReceivedMs;
public final String reason;
@CalledByNative
CandidatePairChangeEvent(
IceCandidate local, IceCandidate remote, int lastDataReceivedMs, String reason) {
this.local = local;
this.remote = remote;
this.lastDataReceivedMs = lastDataReceivedMs;
this.reason = reason;
}
}

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.webrtc.CandidatePairChangeEvent;
import org.webrtc.DataChannel;
import org.webrtc.MediaStreamTrack;
import org.webrtc.RtpTransceiver;
@ -118,6 +119,10 @@ public class PeerConnection {
/** Triggered when some ICE candidates have been removed. */
@CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates);
/** Triggered when the ICE candidate pair is changed. */
@CalledByNative("Observer")
default void onSelectedCandidatePairChanged(CandidatePairChangeEvent event) {}
/** Triggered when media is received on a new stream from remote peer. */
@CalledByNative("Observer") void onAddStream(MediaStream stream);

View File

@ -143,6 +143,9 @@ public class PeerConnectionTest {
@Override
public void onIceCandidatesRemoved(IceCandidate[] candidates) {}
@Override
public void onSelectedCandidatePairChanged(CandidatePairChangeEvent event) {}
// TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
@SuppressWarnings("NoSynchronizedMethodCheck")
public synchronized void setExpectedResolution(int width, int height) {

View File

@ -41,6 +41,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "sdk/android/generated_peerconnection_jni/CandidatePairChangeEvent_jni.h"
#include "sdk/android/generated_peerconnection_jni/PeerConnection_jni.h"
#include "sdk/android/native_api/jni/java_types.h"
#include "sdk/android/src/jni/jni_helpers.h"
@ -120,6 +121,16 @@ SdpSemantics JavaToNativeSdpSemantics(JNIEnv* jni,
return SdpSemantics::kPlanB;
}
ScopedJavaLocalRef<jobject> NativeToJavaCandidatePairChange(
JNIEnv* env,
const cricket::CandidatePairChangeEvent& event) {
return Java_CandidatePairChangeEvent_Constructor(
env, NativeToJavaCandidate(env, event.local_candidate),
NativeToJavaCandidate(env, event.remote_candidate),
static_cast<int>(event.last_data_received_ms),
NativeToJavaString(env, event.reason));
}
} // namespace
void JavaToNativeRTCConfiguration(
@ -325,6 +336,13 @@ void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) {
receiving);
}
void PeerConnectionObserverJni::OnIceSelectedCandidatePairChanged(
const cricket::CandidatePairChangeEvent& event) {
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_Observer_onSelectedCandidatePairChanged(
env, j_observer_global_, NativeToJavaCandidatePairChange(env, event));
}
void PeerConnectionObserverJni::OnIceGatheringChange(
PeerConnectionInterface::IceGatheringState new_state) {
JNIEnv* env = AttachCurrentThreadIfNeeded();

View File

@ -58,6 +58,8 @@ class PeerConnectionObserverJni : public PeerConnectionObserver {
void OnIceConnectionReceivingChange(bool receiving) override;
void OnIceGatheringChange(
PeerConnectionInterface::IceGatheringState new_state) override;
void OnIceSelectedCandidatePairChanged(
const cricket::CandidatePairChangeEvent& event) override;
void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override;
void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream) override;
void OnDataChannel(rtc::scoped_refptr<DataChannelInterface> channel) override;

View File

@ -50,6 +50,8 @@ class PeerConnectionDelegateAdapter : public PeerConnectionObserver {
void OnIceCandidatesRemoved(const std::vector<cricket::Candidate> &candidates) override;
void OnIceSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent &event) override;
void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) override;

View File

@ -147,6 +147,13 @@ RTC_OBJC_EXPORT
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didRemoveReceiver:(RTCRtpReceiver *)rtpReceiver;
/** Called when the selected ICE candidate pair is changed. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didChangeLocalCandidate:(RTCIceCandidate *)local
remoteCandidate:(RTCIceCandidate *)remote
lastReceivedMs:(int)lastDataReceivedMs
changeReason:(NSString *)reason;
@end
RTC_OBJC_EXPORT

View File

@ -233,20 +233,43 @@ void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
didRemoveIceCandidates:ice_candidates];
}
void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
const cricket::CandidatePairChangeEvent &event) {
std::unique_ptr<JsepIceCandidate> local_candidate_wrapper(
new JsepIceCandidate(event.local_candidate.transport_name(), -1, event.local_candidate));
RTCIceCandidate *local_candidate =
[[RTCIceCandidate alloc] initWithNativeCandidate:local_candidate_wrapper.get()];
std::unique_ptr<JsepIceCandidate> remote_candidate_wrapper(
new JsepIceCandidate(event.remote_candidate.transport_name(), -1, event.remote_candidate));
RTCIceCandidate *remote_candidate =
[[RTCIceCandidate alloc] initWithNativeCandidate:remote_candidate_wrapper.get()];
RTCPeerConnection *peer_connection = peer_connection_;
NSString *nsstr_reason = [NSString stringForStdString:event.reason];
if ([peer_connection.delegate
respondsToSelector:@selector
(peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) {
[peer_connection.delegate peerConnection:peer_connection
didChangeLocalCandidate:local_candidate
remoteCandidate:remote_candidate
lastReceivedMs:event.last_data_received_ms
changeReason:nsstr_reason];
}
}
void PeerConnectionDelegateAdapter::OnAddTrack(
rtc::scoped_refptr<RtpReceiverInterface> receiver,
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) {
RTCPeerConnection *peer_connection = peer_connection_;
if ([peer_connection.delegate
respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
didAddReceiver:streams:)]) {
NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
for (const auto& nativeStream : streams) {
for (const auto &nativeStream : streams) {
RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
nativeMediaStream:nativeStream];
[mediaStreams addObject:mediaStream];
}
RTCRtpReceiver *rtpReceiver =
[[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory
nativeRtpReceiver:receiver];
[peer_connection.delegate peerConnection:peer_connection
didAddReceiver:rtpReceiver
@ -258,15 +281,14 @@ void PeerConnectionDelegateAdapter::OnRemoveTrack(
rtc::scoped_refptr<RtpReceiverInterface> receiver) {
RTCPeerConnection *peer_connection = peer_connection_;
if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
RTCRtpReceiver *rtpReceiver =
[[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory
nativeRtpReceiver:receiver];
[peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
}
}
} // namespace webrtc
@implementation RTCPeerConnection {
RTCPeerConnectionFactory *_factory;
NSMutableArray<RTCMediaStream *> *_localStreams;