Reset the BWE when the network changes.

Currently "Resetting the BWE" does nothing yet. This CL passes the correct signaling to the bandwidth estimator.

BUG=
R=pthatcher@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#12154}
This commit is contained in:
Honghai Zhang 2016-03-29 17:27:21 -07:00
parent f8711c0209
commit cc411c0599
22 changed files with 288 additions and 9 deletions

View File

@ -0,0 +1,44 @@
/*
* Copyright 2016 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.
*/
#ifndef WEBRTC_BASE_NETWORKROUTE_H_
#define WEBRTC_BASE_NETWORKROUTE_H_
// TODO(honghaiz): Make a directory that describes the interfaces and structs
// the media code can rely on and the network code can implement, and both can
// depend on that, but not depend on each other. Then, move this file to that
// directory.
namespace cricket {
struct NetworkRoute {
bool connected;
uint16_t local_network_id;
uint16_t remote_network_id;
NetworkRoute()
: connected(false), local_network_id(0), remote_network_id(0) {}
// The route is connected if the local and remote network ids are provided.
NetworkRoute(uint16_t local_net_id, uint16_t remote_net_id)
: connected(true),
local_network_id(local_net_id),
remote_network_id(remote_net_id) {}
bool operator==(const NetworkRoute& nr) const {
return connected == nr.connected &&
local_network_id == nr.local_network_id &&
remote_network_id == nr.remote_network_id;
}
bool operator!=(const NetworkRoute& nr) const { return !(*this == nr); }
};
} // namespace cricket
#endif // WEBRTC_BASE_NETWORKROUTE_H_

View File

@ -20,6 +20,7 @@
#include "webrtc/audio_sink.h"
#include "webrtc/base/copyonwritebuffer.h"
#include "webrtc/base/networkroute.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/media/base/audiosource.h"
#include "webrtc/media/base/mediaengine.h"
@ -178,6 +179,12 @@ template <class Base> class RtpHelper : public Base {
return ready_to_send_;
}
NetworkRoute last_network_route() const { return last_network_route_; }
int num_network_route_changes() const { return num_network_route_changes_; }
void set_num_network_route_changes(int changes) {
num_network_route_changes_ = changes;
}
protected:
bool MuteStream(uint32_t ssrc, bool mute) {
if (!HasSendStream(ssrc) && ssrc != 0) {
@ -216,6 +223,11 @@ template <class Base> class RtpHelper : public Base {
virtual void OnReadyToSend(bool ready) {
ready_to_send_ = ready;
}
virtual void OnNetworkRouteChanged(const std::string& transport_name,
const NetworkRoute& network_route) {
last_network_route_ = network_route;
++num_network_route_changes_;
}
bool fail_set_send_codecs() const { return fail_set_send_codecs_; }
bool fail_set_recv_codecs() const { return fail_set_recv_codecs_; }
@ -235,6 +247,8 @@ template <class Base> class RtpHelper : public Base {
uint32_t send_ssrc_;
std::string rtcp_cname_;
bool ready_to_send_;
NetworkRoute last_network_route_;
int num_network_route_changes_ = 0;
};
class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {

View File

@ -20,6 +20,7 @@
#include "webrtc/base/copyonwritebuffer.h"
#include "webrtc/base/dscp.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/networkroute.h"
#include "webrtc/base/optional.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/socket.h"
@ -387,6 +388,9 @@ class MediaChannel : public sigslot::has_slots<> {
const rtc::PacketTime& packet_time) = 0;
// Called when the socket's ability to send has changed.
virtual void OnReadyToSend(bool ready) = 0;
// Called when the network route used for sending packets changed.
virtual void OnNetworkRouteChanged(const std::string& transport_name,
const NetworkRoute& network_route) = 0;
// Creates a new outgoing media stream with SSRCs and CNAME as described
// by sp.
virtual bool AddSendStream(const StreamParams& sp) = 0;
@ -1104,6 +1108,9 @@ class DataMediaChannel : public MediaChannel {
virtual bool SetSend(bool send) = 0;
virtual bool SetReceive(bool receive) = 0;
virtual void OnNetworkRouteChanged(const std::string& transport_name,
const NetworkRoute& network_route) {}
virtual bool SendData(
const SendDataParams& params,
const rtc::CopyOnWriteBuffer& payload,

View File

@ -1410,6 +1410,13 @@ void WebRtcVideoChannel2::OnReadyToSend(bool ready) {
ready ? webrtc::kNetworkUp : webrtc::kNetworkDown);
}
void WebRtcVideoChannel2::OnNetworkRouteChanged(
const std::string& transport_name,
const NetworkRoute& network_route) {
// TODO(honghaiz): uncomment this once the function in call is implemented.
// call_->OnNetworkRouteChanged(transport_name, network_route);
}
bool WebRtcVideoChannel2::MuteStream(uint32_t ssrc, bool mute) {
LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> "
<< (mute ? "mute" : "unmute");

View File

@ -19,6 +19,7 @@
#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/networkroute.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/media/base/videosinkinterface.h"
@ -167,6 +168,8 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport {
void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketTime& packet_time) override;
void OnReadyToSend(bool ready) override;
void OnNetworkRouteChanged(const std::string& transport_name,
const NetworkRoute& network_route) override;
void SetInterface(NetworkInterface* iface) override;
// Implemented for VideoMediaChannelTest.

View File

@ -2328,6 +2328,13 @@ void WebRtcVoiceMediaChannel::OnRtcpReceived(
}
}
void WebRtcVoiceMediaChannel::OnNetworkRouteChanged(
const std::string& transport_name,
const NetworkRoute& network_route) {
// TODO(honghaiz): uncomment this once the function in call is implemented.
// call_->OnNetworkRouteChanged(transport_name, network_route);
}
bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
int channel = GetSendChannelId(ssrc);

View File

@ -18,6 +18,7 @@
#include "webrtc/audio_state.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/networkroute.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/call.h"
@ -183,6 +184,8 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
const rtc::PacketTime& packet_time) override;
void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketTime& packet_time) override;
void OnNetworkRouteChanged(const std::string& transport_name,
const NetworkRoute& network_route) override;
void OnReadyToSend(bool ready) override;
bool GetStats(VoiceMediaInfo* info) override;

View File

@ -0,0 +1,28 @@
/*
* Copyright 2016 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.
*/
#ifndef WEBRTC_P2P_BASE_CANDIDATEPAIRINTERFACE_H_
#define WEBRTC_P2P_BASE_CANDIDATEPAIRINTERFACE_H_
namespace cricket {
class Candidate;
class CandidatePairInterface {
public:
virtual ~CandidatePairInterface() {}
virtual const Candidate& local_candidate() const = 0;
virtual const Candidate& remote_candidate() const = 0;
};
} // namespace cricket
#endif // WEBRTC_P2P_BASE_CANDIDATEPAIRINTERFACE_H_

View File

@ -119,6 +119,8 @@ DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
&DtlsTransportChannelWrapper::OnRoleConflict);
channel_->SignalRouteChange.connect(this,
&DtlsTransportChannelWrapper::OnRouteChange);
channel_->SignalSelectedCandidatePairChanged.connect(
this, &DtlsTransportChannelWrapper::OnSelectedCandidatePairChanged);
channel_->SignalConnectionRemoved.connect(this,
&DtlsTransportChannelWrapper::OnConnectionRemoved);
channel_->SignalReceivingState.connect(this,
@ -634,6 +636,13 @@ void DtlsTransportChannelWrapper::OnRouteChange(
SignalRouteChange(this, candidate);
}
void DtlsTransportChannelWrapper::OnSelectedCandidatePairChanged(
TransportChannel* channel,
CandidatePairInterface* selected_candidate_pair) {
ASSERT(channel == channel_);
SignalSelectedCandidatePairChanged(this, selected_candidate_pair);
}
void DtlsTransportChannelWrapper::OnConnectionRemoved(
TransportChannelImpl* channel) {
ASSERT(channel == channel_);

View File

@ -216,6 +216,9 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
const Candidates& candidates);
void OnRoleConflict(TransportChannelImpl* channel);
void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
void OnSelectedCandidatePairChanged(
TransportChannel* channel,
CandidatePairInterface* selected_candidate_pair);
void OnConnectionRemoved(TransportChannelImpl* channel);
void Reconnect();

View File

@ -15,6 +15,7 @@
#include <string>
#include <vector>
#include "webrtc/p2p/base/candidatepairinterface.h"
#include "webrtc/p2p/base/transport.h"
#include "webrtc/p2p/base/transportchannel.h"
#include "webrtc/p2p/base/transportcontroller.h"
@ -452,6 +453,24 @@ class FakeTransport : public Transport {
rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
};
// Fake candidate pair class, which can be passed to BaseChannel for testing
// purposes.
class FakeCandidatePair : public CandidatePairInterface {
public:
FakeCandidatePair(const Candidate& local_candidate,
const Candidate& remote_candidate)
: local_candidate_(local_candidate),
remote_candidate_(remote_candidate) {}
const Candidate& local_candidate() const override { return local_candidate_; }
const Candidate& remote_candidate() const override {
return remote_candidate_;
}
private:
Candidate local_candidate_;
Candidate remote_candidate_;
};
// Fake TransportController class, which can be passed into a BaseChannel object
// for test purposes. Can be connected to other FakeTransportControllers via
// Connect().
@ -503,6 +522,18 @@ class FakeTransportController : public TransportController {
component);
}
FakeCandidatePair* CreateFakeCandidatePair(
const rtc::SocketAddress& local_address,
int16_t local_network_id,
const rtc::SocketAddress& remote_address,
int16_t remote_network_id) {
Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0,
"foundation", local_network_id, 0);
Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0,
"foundation", remote_network_id, 0);
return new FakeCandidatePair(local_candidate, remote_candidate);
}
void set_fail_channel_creation(bool fail_channel_creation) {
fail_create_channel_ = fail_channel_creation;
}

View File

@ -18,6 +18,7 @@
#include "webrtc/base/logging.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/p2p/base/candidate.h"
#include "webrtc/p2p/base/candidatepairinterface.h"
#include "webrtc/p2p/base/common.h"
#include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE.
#include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE.
@ -1165,6 +1166,9 @@ void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) {
} else {
LOG_J(LS_INFO, this) << "No best connection";
}
// TODO(honghaiz): rename best_connection_ with selected_connection_ or
// selected_candidate pair_.
SignalSelectedCandidatePairChanged(this, best_connection_);
}
// Warning: UpdateState should eventually be called whenever a connection

View File

@ -25,6 +25,7 @@
#include <string>
#include <vector>
#include "webrtc/p2p/base/candidate.h"
#include "webrtc/p2p/base/candidatepairinterface.h"
#include "webrtc/p2p/base/p2ptransport.h"
#include "webrtc/p2p/base/portallocator.h"
#include "webrtc/p2p/base/portinterface.h"

View File

@ -317,6 +317,8 @@ class P2PTransportChannelTestBase : public testing::Test,
this, &P2PTransportChannelTestBase::OnReadPacket);
channel->SignalRoleConflict.connect(
this, &P2PTransportChannelTestBase::OnRoleConflict);
channel->SignalSelectedCandidatePairChanged.connect(
this, &P2PTransportChannelTestBase::OnSelectedCandidatePairChanged);
channel->SetIceCredentials(local_ice_ufrag, local_ice_pwd);
if (clear_remote_candidates_ufrag_pwd_) {
// This only needs to be set if we're clearing them from the
@ -741,6 +743,13 @@ class P2PTransportChannelTestBase : public testing::Test,
cricket::ICEROLE_CONTROLLED : cricket::ICEROLE_CONTROLLING;
channel->SetIceRole(new_role);
}
void OnSelectedCandidatePairChanged(
cricket::TransportChannel* channel,
cricket::CandidatePairInterface* candidate_pair) {
++num_selected_candidate_pair_changes_;
}
int SendData(cricket::TransportChannel* channel,
const char* data, size_t len) {
rtc::PacketOptions options;
@ -794,6 +803,13 @@ class P2PTransportChannelTestBase : public testing::Test,
force_relay_ = relay;
}
int num_selected_candidate_pair_changes() {
return num_selected_candidate_pair_changes_;
}
void set_num_selected_candidate_pair_changes(int num) {
num_selected_candidate_pair_changes_ = num;
}
private:
rtc::Thread* main_;
rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
@ -808,6 +824,7 @@ class P2PTransportChannelTestBase : public testing::Test,
rtc::SocksProxyServer socks_server2_;
Endpoint ep1_;
Endpoint ep2_;
int num_selected_candidate_pair_changes_ = 0;
bool clear_remote_candidates_ufrag_pwd_;
bool force_relay_;
};
@ -1578,8 +1595,9 @@ TEST_F(P2PTransportChannelMultihomedTest, DISABLED_TestBasic) {
Test(kLocalUdpToLocalUdp);
}
// Test that we can quickly switch links if an interface goes down.
// The controlled side has two interfaces and one will die.
// Test that we can quickly switch links if an interface goes down. This also
// tests that when the link switches, |SignalSelectedCandidatePairChanged| will
// be fired. The controlled side has two interfaces and one will die.
TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
AddAddress(0, kPublicAddrs[0]);
// Adding alternate address will make sure |kPublicAddrs| has the higher
@ -1607,6 +1625,7 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
ep1_ch1()->SetIceConfig(config);
ep2_ch1()->SetIceConfig(config);
set_num_selected_candidate_pair_changes(0);
// Blackhole any traffic to or from the public addrs.
LOG(LS_INFO) << "Failing over...";
fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
@ -1627,12 +1646,15 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
EXPECT_TRUE(
LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
// It should have changed twice, one on each side.
EXPECT_EQ(2, num_selected_candidate_pair_changes());
DestroyChannels();
}
// Test that we can quickly switch links if an interface goes down.
// The controlling side has two interfaces and one will die.
// Test that we can quickly switch links if an interface goes down. This also
// tests that when the link switches, |SignalSelectedCandidatePairChanged| will
// be fired. The controlling side has two interfaces and one will die.
TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
// Adding alternate address will make sure |kPublicAddrs| has the higher
// priority than others. This is due to FakeNetwork::AddInterface method.
@ -1658,6 +1680,7 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
cricket::IceConfig config = CreateIceConfig(1000, false);
ep1_ch1()->SetIceConfig(config);
ep2_ch1()->SetIceConfig(config);
set_num_selected_candidate_pair_changes(0);
// Blackhole any traffic to or from the public addrs.
LOG(LS_INFO) << "Failing over...";
@ -1679,6 +1702,7 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
EXPECT_TRUE(
RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
EXPECT_EQ(2, num_selected_candidate_pair_changes());
DestroyChannels();
}

View File

@ -813,6 +813,10 @@ const Candidate& Connection::local_candidate() const {
return port_->Candidates()[local_candidate_index_];
}
const Candidate& Connection::remote_candidate() const {
return remote_candidate_;
}
uint64_t Connection::priority() const {
uint64_t priority = 0;
// RFC 5245 - 5.7.2. Computing Pair Priority and Ordering Pairs

View File

@ -17,6 +17,7 @@
#include <vector>
#include "webrtc/p2p/base/candidate.h"
#include "webrtc/p2p/base/candidatepairinterface.h"
#include "webrtc/p2p/base/packetsocketfactory.h"
#include "webrtc/p2p/base/portinterface.h"
#include "webrtc/p2p/base/stun.h"
@ -410,8 +411,9 @@ class Port : public PortInterface, public rtc::MessageHandler,
// Represents a communication link between a port on the local client and a
// port on the remote client.
class Connection : public rtc::MessageHandler,
public sigslot::has_slots<> {
class Connection : public CandidatePairInterface,
public rtc::MessageHandler,
public sigslot::has_slots<> {
public:
struct SentPing {
SentPing(const std::string id, int64_t sent_time)
@ -435,11 +437,11 @@ class Connection : public rtc::MessageHandler,
Port* port() { return port_; }
const Port* port() const { return port_; }
// Implementation of virtual methods in CandidatePairInterface.
// Returns the description of the local port
virtual const Candidate& local_candidate() const;
// Returns the description of the remote port to which we communicate.
const Candidate& remote_candidate() const { return remote_candidate_; }
virtual const Candidate& remote_candidate() const;
// Returns the pair priority.
uint64_t priority() const;

View File

@ -15,6 +15,7 @@
#include <vector>
#include "webrtc/p2p/base/candidate.h"
#include "webrtc/p2p/base/candidatepairinterface.h"
#include "webrtc/p2p/base/transport.h"
#include "webrtc/p2p/base/transportdescription.h"
#include "webrtc/base/asyncpacketsocket.h"
@ -146,11 +147,18 @@ class TransportChannel : public sigslot::has_slots<> {
// Signalled each time a packet is sent on this channel.
sigslot::signal2<TransportChannel*, const rtc::SentPacket&> SignalSentPacket;
// Deprecated by SignalSelectedCandidatePairChanged
// This signal occurs when there is a change in the way that packets are
// being routed, i.e. to a different remote location. The candidate
// indicates where and how we are currently sending media.
sigslot::signal2<TransportChannel*, const Candidate&> SignalRouteChange;
// Signalled when the current selected candidate pair has changed.
// The first parameter is the transport channel that signals the event.
// The second parameter is the new selected candidate pair.
sigslot::signal2<TransportChannel*, CandidatePairInterface*>
SignalSelectedCandidatePairChanged;
// Invoked when the channel is being destroyed.
sigslot::signal1<TransportChannel*> SignalDestroyed;

View File

@ -140,6 +140,8 @@ QuicTransportChannel::QuicTransportChannel(TransportChannelImpl* channel)
&QuicTransportChannel::OnRoleConflict);
channel_->SignalRouteChange.connect(this,
&QuicTransportChannel::OnRouteChange);
channel_->SignalSelectedCandidatePairChanged.connect(
this, &QuicTransportChannel::OnSelectedCandidatePairChanged);
channel_->SignalConnectionRemoved.connect(
this, &QuicTransportChannel::OnConnectionRemoved);
channel_->SignalReceivingState.connect(
@ -387,6 +389,13 @@ void QuicTransportChannel::OnRouteChange(TransportChannel* channel,
SignalRouteChange(this, candidate);
}
void QuicTransportChannel::OnSelectedCandidatePairChanged(
TransportChannel* channel,
CandidatePairInterface* selected_candidate_pair) {
ASSERT(channel == channel_);
SignalSelectedCandidatePairChanged(this, selected_candidate_pair);
}
void QuicTransportChannel::OnConnectionRemoved(TransportChannelImpl* channel) {
ASSERT(channel == channel_);
SignalConnectionRemoved(this);

View File

@ -230,6 +230,9 @@ class QuicTransportChannel : public TransportChannelImpl,
void OnCandidateGathered(TransportChannelImpl* channel, const Candidate& c);
void OnRoleConflict(TransportChannelImpl* channel);
void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
void OnSelectedCandidatePairChanged(
TransportChannel* channel,
CandidatePairInterface* selected_candidate_pair);
void OnConnectionRemoved(TransportChannelImpl* channel);
// Callbacks for |quic_|.

View File

@ -19,6 +19,7 @@
#include "webrtc/base/copyonwritebuffer.h"
#include "webrtc/base/dscp.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/networkroute.h"
#include "webrtc/base/trace_event.h"
#include "webrtc/media/base/mediaconstants.h"
#include "webrtc/media/base/rtputils.h"
@ -346,6 +347,8 @@ void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) {
tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead);
tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend);
tc->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState);
tc->SignalSelectedCandidatePairChanged.connect(
this, &BaseChannel::OnSelectedCandidatePairChanged);
}
void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) {
@ -504,6 +507,20 @@ void BaseChannel::OnDtlsState(TransportChannel* channel,
}
}
void BaseChannel::OnSelectedCandidatePairChanged(
TransportChannel* channel,
CandidatePairInterface* selected_candidate_pair) {
ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
NetworkRoute network_route;
if (selected_candidate_pair) {
network_route =
NetworkRoute(selected_candidate_pair->local_candidate().network_id(),
selected_candidate_pair->remote_candidate().network_id());
}
media_channel()->OnNetworkRouteChanged(channel->transport_name(),
network_route);
}
void BaseChannel::SetReadyToSend(bool rtcp, bool ready) {
if (rtcp) {
rtcp_ready_to_send_ = ready;

View File

@ -207,6 +207,10 @@ class BaseChannel
void OnDtlsState(TransportChannel* channel, DtlsTransportState state);
void OnSelectedCandidatePairChanged(
TransportChannel* channel,
CandidatePairInterface* selected_candidate_pair);
bool PacketIsRtcp(const TransportChannel* channel, const char* data,
size_t len);
bool SendPacket(bool rtcp,

View File

@ -490,6 +490,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
}
}
cricket::CandidatePairInterface* last_selected_candidate_pair() {
return last_selected_candidate_pair_;
}
void AddLegacyStreamInContent(uint32_t ssrc,
int flags,
typename T::Content* content) {
@ -951,6 +955,41 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
EXPECT_TRUE(media_channel2_->sending());
}
// Tests that when the transport channel signals a candidate pair change
// event, the media channel will receive a call on the network route change.
void TestNetworkRouteChanges() {
CreateChannels(0, 0);
cricket::TransportChannel* transport_channel1 =
channel1_->transport_channel();
ASSERT_TRUE(transport_channel1 != nullptr);
typename T::MediaChannel* media_channel1 =
static_cast<typename T::MediaChannel*>(channel1_->media_channel());
ASSERT_TRUE(media_channel1 != nullptr);
media_channel1_->set_num_network_route_changes(0);
// The transport channel becomes disconnected.
transport_channel1->SignalSelectedCandidatePairChanged(transport_channel1,
nullptr);
EXPECT_EQ(1, media_channel1_->num_network_route_changes());
EXPECT_FALSE(media_channel1->last_network_route().connected);
media_channel1_->set_num_network_route_changes(0);
// The transport channel becomes connected.
rtc::SocketAddress local_address("192.168.1.1", 1000 /* port number */);
rtc::SocketAddress remote_address("192.168.1.2", 2000 /* port number */);
uint16_t local_net_id = 1;
uint16_t remote_net_id = 2;
rtc::scoped_ptr<cricket::CandidatePairInterface> candidate_pair(
transport_controller1_.CreateFakeCandidatePair(
local_address, local_net_id, remote_address, remote_net_id));
transport_channel1->SignalSelectedCandidatePairChanged(
transport_channel1, candidate_pair.get());
EXPECT_EQ(1, media_channel1_->num_network_route_changes());
cricket::NetworkRoute expected_network_route(local_net_id, remote_net_id);
EXPECT_EQ(expected_network_route, media_channel1->last_network_route());
}
// Test setting up a call.
void TestCallSetup() {
CreateChannels(0, 0);
@ -1871,6 +1910,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
std::string rtcp_packet_;
int media_info_callbacks1_;
int media_info_callbacks2_;
cricket::CandidatePairInterface* last_selected_candidate_pair_;
};
template<>
@ -1996,7 +2036,6 @@ class VideoChannelTest
// VoiceChannelTest
TEST_F(VoiceChannelTest, TestInit) {
Base::TestInit();
EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
@ -2069,6 +2108,10 @@ TEST_F(VoiceChannelTest, TestMediaContentDirection) {
Base::TestMediaContentDirection();
}
TEST_F(VoiceChannelTest, TestNetworkRouteChanges) {
Base::TestNetworkRouteChanges();
}
TEST_F(VoiceChannelTest, TestCallSetup) {
Base::TestCallSetup();
}
@ -2399,6 +2442,10 @@ TEST_F(VideoChannelTest, TestMediaContentDirection) {
Base::TestMediaContentDirection();
}
TEST_F(VideoChannelTest, TestNetworkRouteChanges) {
Base::TestNetworkRouteChanges();
}
TEST_F(VideoChannelTest, TestCallSetup) {
Base::TestCallSetup();
}