Add methods to set the ICE connection receiving_timeout values.

BUG=

Review URL: https://codereview.webrtc.org/1231913003

Cr-Commit-Position: refs/heads/master@{#9572}
This commit is contained in:
honghaiz
2015-07-13 12:19:33 -07:00
committed by Commit bot
parent 45d1fdee9d
commit 900996290c
19 changed files with 196 additions and 24 deletions

View File

@ -1486,6 +1486,13 @@ JOW(void, PeerConnection_setRemoteDescription)(
observer, JavaSdpToNativeSdp(jni, j_sdp));
}
JOW(void, PeerConnection_setIceConnectionReceivingTimeout)(JNIEnv* jni,
jobject j_pc,
jint timeout_ms) {
return ExtractNativePC(jni, j_pc)
->SetIceConnectionReceivingTimeout(timeout_ms);
}
JOW(jboolean, PeerConnection_updateIce)(
JNIEnv* jni, jobject j_pc, jobject j_ice_servers, jobject j_constraints) {
PeerConnectionInterface::IceServers ice_servers;

View File

@ -180,6 +180,8 @@ public class PeerConnection {
public native void setRemoteDescription(
SdpObserver observer, SessionDescription sdp);
public native void setIceConnectionReceivingTimeout(int timeoutMs);
public native boolean updateIce(
List<IceServer> iceServers, MediaConstraints constraints);

View File

@ -650,6 +650,10 @@ void PeerConnection::PostSetSessionDescriptionFailure(
signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
}
void PeerConnection::SetIceConnectionReceivingTimeout(int timeout_ms) {
session_->SetIceConnectionReceivingTimeout(timeout_ms);
}
bool PeerConnection::UpdateIce(const IceServers& configuration,
const MediaConstraintsInterface* constraints) {
return false;

View File

@ -99,6 +99,7 @@ class PeerConnection : public PeerConnectionInterface,
SessionDescriptionInterface* desc);
virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc);
virtual void SetIceConnectionReceivingTimeout(int timeout_ms);
// TODO(mallinath) : Deprecated version, remove after all clients are updated.
virtual bool UpdateIce(const IceServers& configuration,
const MediaConstraintsInterface* constraints);

View File

@ -335,6 +335,8 @@ class PeerConnectionInterface : public rtc::RefCountInterface {
// The |observer| callback will be called when done.
virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc) = 0;
// Sets the ICE connection receiving timeout value in milliseconds.
virtual void SetIceConnectionReceivingTimeout(int timeout_ms) = 0;
// Restarts or updates the ICE Agent process of gathering local candidates
// and pinging remote candidates.
virtual bool UpdateIce(const IceServers& configuration,

View File

@ -62,6 +62,7 @@ BEGIN_PROXY_MAP(PeerConnection)
const MediaConstraintsInterface*)
PROXY_METHOD1(bool, AddIceCandidate, const IceCandidateInterface*)
PROXY_METHOD1(void, RegisterUMAObserver, UMAObserver*)
PROXY_METHOD1(void, SetIceConnectionReceivingTimeout, int)
PROXY_METHOD0(SignalingState, signaling_state)
PROXY_METHOD0(IceState, ice_state)
PROXY_METHOD0(IceConnectionState, ice_connection_state)

View File

@ -204,6 +204,10 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
channel_->OnCandidate(candidate);
}
void SetReceivingTimeout(int receiving_timeout_ms) {
channel_->SetReceivingTimeout(receiving_timeout_ms);
}
// Needed by DtlsTransport.
TransportChannelImpl* channel() { return channel_; }

View File

@ -181,6 +181,8 @@ class FakeTransportChannel : public TransportChannelImpl,
set_receiving(receiving);
}
void SetReceivingTimeout(int timeout) override {}
virtual int SendPacket(const char* data, size_t len,
const rtc::PacketOptions& options, int flags) {
if (state_ != STATE_CONNECTED) {

View File

@ -359,10 +359,15 @@ void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
remote_ice_mode_ = mode;
}
void P2PTransportChannel::set_receiving_timeout(int receiving_timeout_ms) {
void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) {
if (receiving_timeout_ms < 0) {
return;
}
receiving_timeout_ = receiving_timeout_ms;
check_receiving_delay_ =
std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10);
LOG(LS_VERBOSE) << "Set ICE receiving timeout to " << receiving_timeout_
<< " milliseconds";
}
// Go into the state of processing candidates, and running in general

View File

@ -87,7 +87,7 @@ class P2PTransportChannel : public TransportChannelImpl,
// Sets the receiving timeout in milliseconds.
// This also sets the check_receiving_delay proportionally.
void set_receiving_timeout(int receiving_timeout_ms);
void SetReceivingTimeout(int receiving_timeout_ms) override;
// Note: This is only for testing purpose.
// |ports_| should not be changed from outside.

View File

@ -1870,7 +1870,7 @@ TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
// small.
EXPECT_LE(1000, ch.receiving_timeout());
EXPECT_LE(200, ch.check_receiving_delay());
ch.set_receiving_timeout(500);
ch.SetReceivingTimeout(500);
EXPECT_EQ(500, ch.receiving_timeout());
EXPECT_EQ(50, ch.check_receiving_delay());
ch.Connect();

View File

@ -156,6 +156,8 @@ class RawTransportChannel : public TransportChannelImpl,
return false;
}
void SetReceivingTimeout(int timeout) override {}
private:
RawTransport* raw_transport_;
rtc::Thread *worker_thread_;

View File

@ -344,7 +344,8 @@ BaseSession::BaseSession(rtc::Thread* signaling_thread,
identity_(NULL),
ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10),
ice_tiebreaker_(rtc::CreateRandomId64()),
role_switch_(false) {
role_switch_(false),
ice_receiving_timeout_(-1) {
ASSERT(signaling_thread->IsCurrent());
}
@ -477,6 +478,16 @@ bool BaseSession::PushdownRemoteTransportDescription(
return true;
}
void BaseSession::SetIceConnectionReceivingTimeout(int timeout_ms) {
ice_receiving_timeout_ = timeout_ms;
for (const auto& kv : transport_proxies()) {
Transport* transport = kv.second->impl();
if (transport) {
transport->SetChannelReceivingTimeout(timeout_ms);
}
}
}
TransportChannel* BaseSession::CreateChannel(const std::string& content_name,
int component) {
// We create the proxy "on demand" here because we need to support
@ -566,12 +577,13 @@ void BaseSession::DestroyTransportProxy(
}
}
cricket::Transport* BaseSession::CreateTransport(
const std::string& content_name) {
Transport* BaseSession::CreateTransport(const std::string& content_name) {
ASSERT(transport_type_ == NS_GINGLE_P2P);
return new cricket::DtlsTransport<P2PTransport>(
signaling_thread(), worker_thread(), content_name,
port_allocator(), identity_);
Transport* transport = new DtlsTransport<P2PTransport>(
signaling_thread(), worker_thread(), content_name, port_allocator(),
identity_);
transport->SetChannelReceivingTimeout(ice_receiving_timeout_);
return transport;
}
void BaseSession::SetState(State state) {

View File

@ -319,6 +319,9 @@ class BaseSession : public sigslot::has_slots<>,
rtc::SSLIdentity* identity() { return identity_; }
// Set the ice connection receiving timeout.
void SetIceConnectionReceivingTimeout(int timeout_ms);
protected:
// Specifies the identity to use in this session.
bool SetIdentity(rtc::SSLIdentity* identity);
@ -453,6 +456,10 @@ class BaseSession : public sigslot::has_slots<>,
// will enable us to stop any role switch during the call.
bool role_switch_;
TransportMap transports_;
// Timeout value in milliseconds for which no ICE connection receives
// any packets.
int ice_receiving_timeout_;
};
} // namespace cricket

View File

@ -0,0 +1,100 @@
/*
* Copyright 2015 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.
*/
#include "webrtc/base/gunit.h"
#include "webrtc/base/helpers.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread.h"
#include "webrtc/p2p/base/dtlstransportchannel.h"
#include "webrtc/p2p/base/p2ptransportchannel.h"
#include "webrtc/p2p/base/portallocator.h"
#include "webrtc/p2p/base/session.h"
#include "webrtc/p2p/base/transportchannelproxy.h"
#include "webrtc/p2p/client/fakeportallocator.h"
using cricket::BaseSession;
using cricket::DtlsTransportChannelWrapper;
using cricket::FakePortAllocator;
using cricket::P2PTransportChannel;
using cricket::PortAllocator;
using cricket::TransportChannelProxy;
using cricket::TransportProxy;
class BaseSessionForTest : public BaseSession {
public:
BaseSessionForTest(rtc::Thread* signaling_thread,
rtc::Thread* worker_thread,
PortAllocator* port_allocator,
const std::string& sid,
const std::string& content_type,
bool initiator)
: BaseSession(signaling_thread,
worker_thread,
port_allocator,
sid,
content_type,
initiator) {}
using BaseSession::GetOrCreateTransportProxy;
};
class BaseSessionTest : public testing::Test {
public:
BaseSessionTest()
: port_allocator_(new FakePortAllocator(rtc::Thread::Current(), nullptr)),
session_(new BaseSessionForTest(rtc::Thread::Current(),
rtc::Thread::Current(),
port_allocator_.get(),
"123",
cricket::NS_JINGLE_RTP,
false)) {}
P2PTransportChannel* CreateChannel(const std::string& content,
int component) {
TransportProxy* transport_proxy =
session_->GetOrCreateTransportProxy(content);
// This hacking is needed in order that the p2p transport channel
// will be created in the following.
transport_proxy->CompleteNegotiation();
TransportChannelProxy* channel_proxy = static_cast<TransportChannelProxy*>(
session_->CreateChannel(content, component));
DtlsTransportChannelWrapper* dtls_channel =
static_cast<DtlsTransportChannelWrapper*>(channel_proxy->impl());
return static_cast<P2PTransportChannel*>(dtls_channel->channel());
}
rtc::scoped_ptr<PortAllocator> port_allocator_;
rtc::scoped_ptr<BaseSessionForTest> session_;
};
TEST_F(BaseSessionTest, TestSetIceReceivingTimeout) {
P2PTransportChannel* channel1 = CreateChannel("audio", 1);
ASSERT_NE(channel1, nullptr);
// These are the default values.
EXPECT_EQ(2500, channel1->receiving_timeout());
EXPECT_EQ(250, channel1->check_receiving_delay());
// Set the timeout to a different value.
session_->SetIceConnectionReceivingTimeout(1000);
EXPECT_EQ(1000, channel1->receiving_timeout());
EXPECT_EQ(100, channel1->check_receiving_delay());
// Even if a channel is created after setting the receiving timeout,
// the set timeout value is applied to the new channel.
P2PTransportChannel* channel2 = CreateChannel("video", 2);
ASSERT_NE(channel2, nullptr);
EXPECT_EQ(1000, channel2->receiving_timeout());
EXPECT_EQ(100, channel2->check_receiving_delay());
// Test minimum checking delay.
session_->SetIceConnectionReceivingTimeout(200);
EXPECT_EQ(200, channel1->receiving_timeout());
EXPECT_EQ(50, channel1->check_receiving_delay());
EXPECT_EQ(200, channel2->receiving_timeout());
EXPECT_EQ(50, channel2->check_receiving_delay());
}

View File

@ -121,21 +121,22 @@ Transport::Transport(rtc::Thread* signaling_thread,
const std::string& content_name,
const std::string& type,
PortAllocator* allocator)
: signaling_thread_(signaling_thread),
worker_thread_(worker_thread),
content_name_(content_name),
type_(type),
allocator_(allocator),
destroyed_(false),
readable_(TRANSPORT_STATE_NONE),
writable_(TRANSPORT_STATE_NONE),
receiving_(TRANSPORT_STATE_NONE),
was_writable_(false),
connect_requested_(false),
ice_role_(ICEROLE_UNKNOWN),
tiebreaker_(0),
protocol_(ICEPROTO_HYBRID),
remote_ice_mode_(ICEMODE_FULL) {
: signaling_thread_(signaling_thread),
worker_thread_(worker_thread),
content_name_(content_name),
type_(type),
allocator_(allocator),
destroyed_(false),
readable_(TRANSPORT_STATE_NONE),
writable_(TRANSPORT_STATE_NONE),
receiving_(TRANSPORT_STATE_NONE),
was_writable_(false),
connect_requested_(false),
ice_role_(ICEROLE_UNKNOWN),
tiebreaker_(0),
protocol_(ICEPROTO_HYBRID),
remote_ice_mode_(ICEMODE_FULL),
channel_receiving_timeout_(-1) {
}
Transport::~Transport() {
@ -174,6 +175,19 @@ bool Transport::GetRemoteCertificate_w(rtc::SSLCertificate** cert) {
return iter->second->GetRemoteCertificate(cert);
}
void Transport::SetChannelReceivingTimeout(int timeout_ms) {
worker_thread_->Invoke<void>(
Bind(&Transport::SetChannelReceivingTimeout_w, this, timeout_ms));
}
void Transport::SetChannelReceivingTimeout_w(int timeout_ms) {
ASSERT(worker_thread()->IsCurrent());
channel_receiving_timeout_ = timeout_ms;
for (const auto& kv : channels_) {
kv.second->SetReceivingTimeout(timeout_ms);
}
}
bool Transport::SetLocalTransportDescription(
const TransportDescription& description,
ContentAction action,
@ -233,6 +247,7 @@ TransportChannelImpl* Transport::CreateChannel_w(int component) {
// Push down our transport state to the new channel.
impl->SetIceRole(ice_role_);
impl->SetIceTiebreaker(tiebreaker_);
impl->SetReceivingTimeout(channel_receiving_timeout_);
// TODO(ronghuawu): Change CreateChannel_w to be able to return error since
// below Apply**Description_w calls can fail.
if (local_description_)

View File

@ -200,6 +200,8 @@ class Transport : public rtc::MessageHandler,
void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
uint64 IceTiebreaker() { return tiebreaker_; }
void SetChannelReceivingTimeout(int timeout_ms);
// Must be called before applying local session description.
void SetIdentity(rtc::SSLIdentity* identity);
@ -438,6 +440,8 @@ class Transport : public rtc::MessageHandler,
bool GetStats_w(TransportStats* infos);
bool GetRemoteCertificate_w(rtc::SSLCertificate** cert);
void SetChannelReceivingTimeout_w(int timeout_ms);
// Sends SignalCompleted if we are now in that state.
void MaybeCompleted_w();
@ -456,6 +460,7 @@ class Transport : public rtc::MessageHandler,
uint64 tiebreaker_;
TransportProtocol protocol_;
IceMode remote_ice_mode_;
int channel_receiving_timeout_;
rtc::scoped_ptr<TransportDescription> local_description_;
rtc::scoped_ptr<TransportDescription> remote_description_;

View File

@ -52,6 +52,8 @@ class TransportChannelImpl : public TransportChannel {
// SetRemoteIceMode must be implemented only by the ICE transport channels.
virtual void SetRemoteIceMode(IceMode mode) = 0;
virtual void SetReceivingTimeout(int timeout_ms) = 0;
// Begins the process of attempting to make a connection to the other client.
virtual void Connect() = 0;

View File

@ -21,6 +21,7 @@
'base/pseudotcp_unittest.cc',
'base/relayport_unittest.cc',
'base/relayserver_unittest.cc',
'base/session_unittest.cc',
'base/stun_unittest.cc',
'base/stunport_unittest.cc',
'base/stunrequest_unittest.cc',