Prepare WebRtcSession to be merged into PeerConnection

This commit prepares WebRtcSession so that it can be cleanly
copy & pasted into PeerConnection in the next commit. To accomplish
this, the following was done:
1. Added a pointer to the owning PeerConnection to WebRtcSession.
2. Replace WebRtcSession state enum with signaling state.
3. All signals/observers only observed by PeerConnection were
   replaced with direct calls to PeerConnection methods.
4. All duplicated fields were moved to PeerConnection.
5. The remaining tests that still use WebRtcSession for mocks were
   updated to minimize dependence on WebRtcSession construction.

Bug: webrtc:8323
Change-Id: Ifc1a4ee819dcc9beca5363291012f7d5563ff7b1
Reviewed-on: https://webrtc-review.googlesource.com/9020
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Reviewed-by: Zhi Huang <zhihuang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20573}
This commit is contained in:
Steve Anton 2017-11-06 10:21:57 -08:00 committed by Commit Bot
parent a1a475a5b6
commit ba818675b9
8 changed files with 362 additions and 589 deletions

View File

@ -45,6 +45,8 @@
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"
namespace webrtc {
namespace {
using webrtc::DataChannel;
@ -241,7 +243,25 @@ bool SafeSetError(webrtc::RTCError error, webrtc::RTCError* error_out) {
} // namespace
namespace webrtc {
std::string GetSignalingStateString(
PeerConnectionInterface::SignalingState state) {
switch (state) {
case PeerConnectionInterface::kStable:
return "kStable";
case PeerConnectionInterface::kHaveLocalOffer:
return "kHaveLocalOffer";
case PeerConnectionInterface::kHaveLocalPrAnswer:
return "kHavePrAnswer";
case PeerConnectionInterface::kHaveRemoteOffer:
return "kHaveRemoteOffer";
case PeerConnectionInterface::kHaveRemotePrAnswer:
return "kHaveRemotePrAnswer";
case PeerConnectionInterface::kClosed:
return "kClosed";
}
RTC_NOTREACHED();
return "";
}
bool PeerConnectionInterface::RTCConfiguration::operator==(
const PeerConnectionInterface::RTCConfiguration& o) const {
@ -393,12 +413,7 @@ PeerConnection::PeerConnection(PeerConnectionFactory* factory,
std::unique_ptr<RtcEventLog> event_log,
std::unique_ptr<Call> call)
: factory_(factory),
observer_(NULL),
uma_observer_(NULL),
event_log_(std::move(event_log)),
signaling_state_(kStable),
ice_connection_state_(kIceConnectionNew),
ice_gathering_state_(kIceGatheringNew),
rtcp_cname_(GenerateRtcpCname()),
local_streams_(StreamCollection::Create()),
remote_streams_(StreamCollection::Create()),
@ -472,44 +487,26 @@ bool PeerConnection::Initialize(
return false;
}
owned_session_.reset(new WebRtcSession(
call_.get(), factory_->channel_manager(), configuration.media_config,
event_log_.get(), network_thread(), worker_thread(), signaling_thread(),
port_allocator_.get(),
std::unique_ptr<cricket::TransportController>(
factory_->CreateTransportController(
port_allocator_.get(),
configuration.redetermine_role_on_ice_restart)),
factory_->CreateSctpTransportInternalFactory()));
owned_session_.reset(
new WebRtcSession(this,
std::unique_ptr<cricket::TransportController>(
factory_->CreateTransportController(
port_allocator_.get(),
configuration.redetermine_role_on_ice_restart)),
factory_->CreateSctpTransportInternalFactory()));
session_ = owned_session_.get();
stats_.reset(new StatsCollector(this));
stats_collector_ = RTCStatsCollector::Create(this);
// Need to set configuration before initializing WebRtcSession because it will
// reach back to fetch the media config.
configuration_ = configuration;
// Initialize the WebRtcSession. It creates transport channels etc.
session_->Initialize(factory_->options(), std::move(cert_generator),
configuration, this);
// Register PeerConnection as receiver of local ice candidates.
// All the callbacks will be posted to the application from PeerConnection.
session_->RegisterIceObserver(this);
session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange);
session_->SignalVoiceChannelCreated.connect(
this, &PeerConnection::OnVoiceChannelCreated);
session_->SignalVoiceChannelDestroyed.connect(
this, &PeerConnection::OnVoiceChannelDestroyed);
session_->SignalVideoChannelCreated.connect(
this, &PeerConnection::OnVideoChannelCreated);
session_->SignalVideoChannelDestroyed.connect(
this, &PeerConnection::OnVideoChannelDestroyed);
session_->SignalDataChannelCreated.connect(
this, &PeerConnection::OnDataChannelCreated);
session_->SignalDataChannelDestroyed.connect(
this, &PeerConnection::OnDataChannelDestroyed);
session_->SignalDataChannelOpenMessage.connect(
this, &PeerConnection::OnDataChannelOpenMessage);
configuration_ = configuration;
return true;
}
@ -1240,7 +1237,7 @@ void PeerConnection::RegisterUMAObserver(UMAObserver* observer) {
uma_observer_ = observer;
if (session_) {
session_->set_metrics_observer(uma_observer_);
session_->transport_controller()->SetMetricsObserver(uma_observer_);
}
// Send information about IPv4/IPv6 status.
@ -1433,35 +1430,6 @@ void PeerConnection::Close() {
});
}
void PeerConnection::OnSessionStateChange(WebRtcSession* /*session*/,
WebRtcSession::State state) {
switch (state) {
case WebRtcSession::STATE_INIT:
ChangeSignalingState(PeerConnectionInterface::kStable);
break;
case WebRtcSession::STATE_SENTOFFER:
ChangeSignalingState(PeerConnectionInterface::kHaveLocalOffer);
break;
case WebRtcSession::STATE_SENTPRANSWER:
ChangeSignalingState(PeerConnectionInterface::kHaveLocalPrAnswer);
break;
case WebRtcSession::STATE_RECEIVEDOFFER:
ChangeSignalingState(PeerConnectionInterface::kHaveRemoteOffer);
break;
case WebRtcSession::STATE_RECEIVEDPRANSWER:
ChangeSignalingState(PeerConnectionInterface::kHaveRemotePrAnswer);
break;
case WebRtcSession::STATE_INPROGRESS:
ChangeSignalingState(PeerConnectionInterface::kStable);
break;
case WebRtcSession::STATE_CLOSED:
ChangeSignalingState(PeerConnectionInterface::kClosed);
break;
default:
break;
}
}
void PeerConnection::OnMessage(rtc::Message* msg) {
switch (msg->message_id) {
case MSG_SET_SESSIONDESCRIPTION_SUCCESS: {
@ -1633,14 +1601,23 @@ void PeerConnection::RemoveVideoTrack(VideoTrackInterface* track,
senders_.erase(sender);
}
void PeerConnection::OnIceConnectionStateChange(
PeerConnectionInterface::IceConnectionState new_state) {
void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
RTC_DCHECK(signaling_thread()->IsCurrent());
if (ice_connection_state_ == new_state) {
return;
}
// After transitioning to "closed", ignore any additional states from
// WebRtcSession (such as "disconnected").
// TransportController (such as "disconnected").
if (IsClosed()) {
return;
}
LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
<< " => " << new_state;
RTC_DCHECK(ice_connection_state_ !=
PeerConnectionInterface::kIceConnectionClosed);
ice_connection_state_ = new_state;
observer_->OnIceConnectionChange(ice_connection_state_);
}
@ -1673,16 +1650,15 @@ void PeerConnection::OnIceCandidatesRemoved(
observer_->OnIceCandidatesRemoved(candidates);
}
void PeerConnection::OnIceConnectionReceivingChange(bool receiving) {
RTC_DCHECK(signaling_thread()->IsCurrent());
if (IsClosed()) {
return;
}
observer_->OnIceConnectionReceivingChange(receiving);
}
void PeerConnection::ChangeSignalingState(
PeerConnectionInterface::SignalingState signaling_state) {
RTC_DCHECK(signaling_thread()->IsCurrent());
if (signaling_state_ == signaling_state) {
return;
}
LOG(LS_INFO) << "Session: " << session_id()
<< " Old state: " << GetSignalingStateString(signaling_state_)
<< " New state: " << GetSignalingStateString(signaling_state);
signaling_state_ = signaling_state;
if (signaling_state == kClosed) {
ice_connection_state_ = kIceConnectionClosed;
@ -2609,6 +2585,14 @@ bool PeerConnection::ReconfigurePortAllocator_n(
turn_customizer);
}
cricket::ChannelManager* PeerConnection::channel_manager() const {
return factory_->channel_manager();
}
MetricsObserverInterface* PeerConnection::metrics_observer() const {
return uma_observer_;
}
bool PeerConnection::StartRtcEventLog_w(
std::unique_ptr<RtcEventLogOutput> output) {
if (!event_log_) {

View File

@ -33,13 +33,19 @@ class MediaStreamObserver;
class VideoRtpReceiver;
class RtcEventLog;
// TODO(steveanton): Remove once WebRtcSession is merged into PeerConnection.
std::string GetSignalingStateString(
PeerConnectionInterface::SignalingState state);
// PeerConnection implements the PeerConnectionInterface interface.
// It uses WebRtcSession to implement the PeerConnection functionality.
class PeerConnection : public PeerConnectionInterface,
public IceObserver,
public rtc::MessageHandler,
public sigslot::has_slots<> {
public:
// TODO(steveanton): Remove once WebRtcSession is merged into PeerConnection.
friend class WebRtcSession;
explicit PeerConnection(PeerConnectionFactory* factory,
std::unique_ptr<RtcEventLog> event_log,
std::unique_ptr<Call> call);
@ -171,15 +177,17 @@ class PeerConnection : public PeerConnectionInterface,
rtc::Thread* network_thread() const { return factory_->network_thread(); }
rtc::Thread* worker_thread() const { return factory_->worker_thread(); }
rtc::Thread* signaling_thread() const { return factory_->signaling_thread(); }
virtual const std::string& session_id() const { return session_->id(); }
virtual const std::string& session_id() const {
return session_->session_id();
}
virtual bool session_created() const { return session_ != nullptr; }
virtual bool initial_offerer() const { return session_->initial_offerer(); }
virtual std::unique_ptr<SessionStats> GetSessionStats_s() {
return session_->GetStats_s();
return session_->GetSessionStats_s();
}
virtual std::unique_ptr<SessionStats> GetSessionStats(
const ChannelNamePairs& channel_name_pairs) {
return session_->GetStats(channel_name_pairs);
return session_->GetSessionStats(channel_name_pairs);
}
virtual bool GetLocalCertificate(
const std::string& transport_name,
@ -270,17 +278,16 @@ class PeerConnection : public PeerConnectionInterface,
void RemoveVideoTrack(VideoTrackInterface* track,
MediaStreamInterface* stream);
// Implements IceObserver
void OnIceConnectionStateChange(IceConnectionState new_state) override;
void OnIceGatheringChange(IceGatheringState new_state) override;
void OnIceCandidate(
std::unique_ptr<IceCandidateInterface> candidate) override;
void SetIceConnectionState(IceConnectionState new_state);
// Called any time the IceGatheringState changes
void OnIceGatheringChange(IceGatheringState new_state);
// New ICE candidate has been gathered.
void OnIceCandidate(std::unique_ptr<IceCandidateInterface> candidate);
// Some local ICE candidates have been removed.
void OnIceCandidatesRemoved(
const std::vector<cricket::Candidate>& candidates) override;
void OnIceConnectionReceivingChange(bool receiving) override;
const std::vector<cricket::Candidate>& candidates);
// Signals from WebRtcSession.
void OnSessionStateChange(WebRtcSession* session, WebRtcSession::State state);
// Update the state, signaling if necessary.
void ChangeSignalingState(SignalingState signaling_state);
// Signals from MediaStreamObserver.
@ -408,15 +415,16 @@ class PeerConnection : public PeerConnectionInterface,
void AllocateSctpSids(rtc::SSLRole role);
void OnSctpDataChannelClosed(DataChannel* channel);
// Notifications from WebRtcSession relating to BaseChannels.
// Called when voice_channel_, video_channel_ and
// rtp_data_channel_/sctp_transport_ are created and destroyed. As a result
// of, for example, setting a new description.
void OnVoiceChannelCreated();
void OnVoiceChannelDestroyed();
void OnVideoChannelCreated();
void OnVideoChannelDestroyed();
void OnDataChannelCreated();
void OnDataChannelDestroyed();
// Called when the cricket::DataChannel receives a message indicating that a
// webrtc::DataChannel should be opened.
// Called when a valid data channel OPEN message is received.
void OnDataChannelOpenMessage(const std::string& label,
const InternalDataChannelInit& config);
@ -466,6 +474,9 @@ class PeerConnection : public PeerConnectionInterface,
// Returns RTCError::OK() if there are no issues.
RTCError ValidateConfiguration(const RTCConfiguration& config) const;
cricket::ChannelManager* channel_manager() const;
MetricsObserverInterface* metrics_observer() const;
// Storing the factory as a scoped reference pointer ensures that the memory
// in the PeerConnectionFactoryImpl remains available as long as the
// PeerConnection is running. It is passed to PeerConnection as a raw pointer.
@ -473,15 +484,15 @@ class PeerConnection : public PeerConnectionInterface,
// PeerConnectionFactoryInterface all instances created using the raw pointer
// will refer to the same reference count.
rtc::scoped_refptr<PeerConnectionFactory> factory_;
PeerConnectionObserver* observer_;
UMAObserver* uma_observer_;
PeerConnectionObserver* observer_ = nullptr;
UMAObserver* uma_observer_ = nullptr;
// The EventLog needs to outlive |call_| (and any other object that uses it).
std::unique_ptr<RtcEventLog> event_log_;
SignalingState signaling_state_;
IceConnectionState ice_connection_state_;
IceGatheringState ice_gathering_state_;
SignalingState signaling_state_ = kStable;
IceConnectionState ice_connection_state_ = kIceConnectionNew;
IceGatheringState ice_gathering_state_ = kIceGatheringNew;
PeerConnectionInterface::RTCConfiguration configuration_;
std::unique_ptr<cricket::PortAllocator> port_allocator_;
@ -512,7 +523,7 @@ class PeerConnection : public PeerConnectionInterface,
bool remote_peer_supports_msid_ = false;
std::unique_ptr<Call> call_;
WebRtcSession* session_;
WebRtcSession* session_ = nullptr;
std::unique_ptr<WebRtcSession> owned_session_;
std::unique_ptr<StatsCollector> stats_; // A pointer is passed to senders_
rtc::scoped_refptr<RTCStatsCollector> stats_collector_;

View File

@ -279,12 +279,10 @@ class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
network_thread_(rtc::Thread::Current()),
signaling_thread_(rtc::Thread::Current()),
media_engine_(new cricket::FakeMediaEngine()),
channel_manager_(new cricket::ChannelManager(
std::unique_ptr<cricket::MediaEngineInterface>(media_engine_),
worker_thread_,
network_thread_)),
session_(channel_manager_.get(), cricket::MediaConfig()),
pc_() {
pc_factory_(new FakePeerConnectionFactory(
std::unique_ptr<cricket::MediaEngineInterface>(media_engine_))),
pc_(pc_factory_),
session_(&pc_) {
pc_.set_session_for_testing(&session_);
// Default return values for mocks.
EXPECT_CALL(pc_, local_streams()).WillRepeatedly(Return(nullptr));
@ -297,7 +295,7 @@ class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
ReturnRef(data_channels_));
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, GetSessionStats(_)).WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, GetLocalCertificate(_, _)).WillRepeatedly(
Return(false));
EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
@ -487,11 +485,11 @@ class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
rtc::Thread* const worker_thread_;
rtc::Thread* const network_thread_;
rtc::Thread* const signaling_thread_;
// |media_engine_| is actually owned by |channel_manager_|.
// |media_engine_| is actually owned by |pc_factory_|.
cricket::FakeMediaEngine* media_engine_;
std::unique_ptr<cricket::ChannelManager> channel_manager_;
MockWebRtcSession session_;
rtc::scoped_refptr<FakePeerConnectionFactory> pc_factory_;
MockPeerConnection pc_;
MockWebRtcSession session_;
std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
std::unique_ptr<cricket::VoiceChannel> voice_channel_;
@ -714,8 +712,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) {
std::vector<std::string>({ "(remote) single certificate" }));
// Mock the session to return the local and remote certificates.
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([](const ChannelNamePairs&) {
std::unique_ptr<SessionStats> stats(new SessionStats());
stats->transport_stats["transport"].transport_name = "transport";
return stats;
@ -805,8 +803,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) {
session_stats.transport_stats["TransportName"].transport_name =
"TransportName";
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
EXPECT_CALL(test_->session(), voice_channel())
@ -885,8 +883,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
video_remote_certinfo->ders);
// Mock the session to return the local and remote certificates.
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([](const ChannelNamePairs&) {
std::unique_ptr<SessionStats> stats(new SessionStats());
stats->transport_stats["audio"].transport_name = "audio";
stats->transport_stats["video"].transport_name = "video";
@ -945,8 +943,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
CreateFakeCertificateAndInfoFromDers(remote_ders);
// Mock the session to return the local and remote certificates.
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([](const ChannelNamePairs&) {
std::unique_ptr<SessionStats> stats(new SessionStats());
stats->transport_stats["transport"].transport_name = "transport";
return stats;
@ -1178,8 +1176,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
b_transport_channel_stats);
// Mock the session to return the desired candidates.
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
@ -1254,8 +1252,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
transport_channel_stats);
// Mock the session to return the desired candidates.
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
@ -1853,8 +1851,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
session_stats.transport_stats["TransportName"].channel_stats.push_back(
channel_stats);
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
EXPECT_CALL(test_->session(), voice_channel())
@ -1936,8 +1934,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
session_stats.transport_stats["TransportName"].channel_stats.push_back(
channel_stats);
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
EXPECT_CALL(test_->session(), video_channel())
@ -2029,8 +2027,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
session_stats.transport_stats["TransportName"].channel_stats.push_back(
channel_stats);
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
EXPECT_CALL(test_->session(), voice_channel())
@ -2111,8 +2109,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
session_stats.transport_stats["TransportName"].channel_stats.push_back(
channel_stats);
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));
EXPECT_CALL(test_->session(), video_channel())
@ -2192,8 +2190,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
// Mock the session to return the desired candidates.
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(test_->session(), GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
}));

View File

@ -568,15 +568,13 @@ class StatsCollectorTest : public testing::Test {
: worker_thread_(rtc::Thread::Current()),
network_thread_(rtc::Thread::Current()),
media_engine_(new cricket::FakeMediaEngine()),
channel_manager_(new cricket::ChannelManager(
std::unique_ptr<cricket::MediaEngineInterface>(media_engine_),
worker_thread_,
network_thread_)),
session_(channel_manager_.get(), cricket::MediaConfig()) {
pc_factory_(new FakePeerConnectionFactory(
std::unique_ptr<cricket::MediaEngineInterface>(media_engine_))),
pc_(pc_factory_),
session_(&pc_) {
pc_.set_session_for_testing(&session_);
// By default, we ignore session GetStats calls.
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, GetSessionStats(_)).WillRepeatedly(ReturnNull());
// Add default returns for mock classes.
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
@ -684,8 +682,8 @@ class StatsCollectorTest : public testing::Test {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(vc_name);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -786,8 +784,8 @@ class StatsCollectorTest : public testing::Test {
EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(
transport_stats.transport_name))
.WillOnce(Return(remote_cert.release()));
EXPECT_CALL(session_, GetStats(_)).WillOnce(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillOnce(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats));
}));
@ -843,11 +841,11 @@ class StatsCollectorTest : public testing::Test {
webrtc::RtcEventLogNullImpl event_log_;
rtc::Thread* const worker_thread_;
rtc::Thread* const network_thread_;
// |media_engine_| is actually owned by |channel_manager_|.
// |media_engine_| is actually owned by |pc_factory_|.
cricket::FakeMediaEngine* media_engine_;
std::unique_ptr<cricket::ChannelManager> channel_manager_;
MockWebRtcSession session_;
rtc::scoped_refptr<FakePeerConnectionFactory> pc_factory_;
MockPeerConnection pc_;
MockWebRtcSession session_;
FakeDataChannelProvider data_channel_provider_;
SessionStats session_stats_;
rtc::scoped_refptr<webrtc::MediaStream> stream_;
@ -929,8 +927,8 @@ TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -978,7 +976,7 @@ TEST_F(StatsCollectorTest, AudioBandwidthEstimationInfoIsReported) {
const char kAudioChannelName[] = "audio";
InitSessionStats(kAudioChannelName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(new SessionStats(session_stats_));
}));
@ -1045,8 +1043,8 @@ TEST_F(StatsCollectorTest, VideoBandwidthEstimationInfoIsReported) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1169,8 +1167,8 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1268,8 +1266,8 @@ TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
Return(true)));
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1341,8 +1339,8 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1386,8 +1384,8 @@ TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1594,8 +1592,8 @@ TEST_F(StatsCollectorTest, NoTransport) {
transport_stats;
// Configure MockWebRtcSession
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats));
}));
@ -1653,8 +1651,8 @@ TEST_F(StatsCollectorTest, NoCertificates) {
transport_stats;
// Configure MockWebRtcSession
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[&session_stats](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([&session_stats](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats));
}));
@ -1734,8 +1732,8 @@ TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1891,8 +1889,8 @@ TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -1967,8 +1965,8 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -2090,8 +2088,8 @@ TEST_F(StatsCollectorTest, VerifyVideoSendSsrcStats) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));
@ -2138,8 +2136,8 @@ TEST_F(StatsCollectorTest, VerifyVideoReceiveSsrcStats) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
[this](const ChannelNamePairs&) {
EXPECT_CALL(session_, GetSessionStats(_))
.WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
return std::unique_ptr<SessionStats>(
new SessionStats(session_stats_));
}));

View File

@ -12,6 +12,7 @@
#define PC_TEST_MOCK_PEERCONNECTION_H_
#include <memory>
#include <utility>
#include <vector>
#include "call/call.h"
@ -26,12 +27,13 @@ namespace webrtc {
class FakePeerConnectionFactory
: public rtc::RefCountedObject<webrtc::PeerConnectionFactory> {
public:
FakePeerConnectionFactory()
FakePeerConnectionFactory(
std::unique_ptr<cricket::MediaEngineInterface> media_engine)
: rtc::RefCountedObject<webrtc::PeerConnectionFactory>(
rtc::Thread::Current(),
rtc::Thread::Current(),
rtc::Thread::Current(),
std::unique_ptr<cricket::MediaEngineInterface>(),
std::move(media_engine),
std::unique_ptr<webrtc::CallFactoryInterface>(),
std::unique_ptr<RtcEventLogFactoryInterface>()) {}
};
@ -39,9 +41,9 @@ class FakePeerConnectionFactory
class MockPeerConnection
: public rtc::RefCountedObject<webrtc::PeerConnection> {
public:
MockPeerConnection()
explicit MockPeerConnection(PeerConnectionFactory* factory)
: rtc::RefCountedObject<webrtc::PeerConnection>(
new FakePeerConnectionFactory(),
factory,
std::unique_ptr<RtcEventLog>(),
std::unique_ptr<Call>()) {}
MOCK_METHOD0(local_streams,

View File

@ -14,8 +14,9 @@
#include <memory>
#include <string>
#include "pc/webrtcsession.h"
#include "media/sctp/sctptransportinternal.h"
#include "pc/test/mock_peerconnection.h"
#include "pc/webrtcsession.h"
#include "test/gmock.h"
namespace webrtc {
@ -26,17 +27,9 @@ class MockWebRtcSession : public webrtc::WebRtcSession {
// methods don't use any override declarations, and we want to avoid
// warnings from -Winconsistent-missing-override. See
// http://crbug.com/428099.
explicit MockWebRtcSession(cricket::ChannelManager* channel_manager,
const cricket::MediaConfig& media_config)
explicit MockWebRtcSession(PeerConnection* pc)
: WebRtcSession(
nullptr, // call
channel_manager,
media_config,
nullptr, // event_log
rtc::Thread::Current(),
rtc::Thread::Current(),
rtc::Thread::Current(),
nullptr,
pc,
std::unique_ptr<cricket::TransportController>(
new cricket::TransportController(
rtc::Thread::Current(),
@ -52,7 +45,7 @@ class MockWebRtcSession : public webrtc::WebRtcSession {
MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32_t, std::string*));
MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32_t, std::string*));
MOCK_METHOD0(GetCallStats, Call::Stats());
MOCK_METHOD1(GetStats,
MOCK_METHOD1(GetSessionStats,
std::unique_ptr<SessionStats>(const ChannelNamePairs&));
MOCK_METHOD2(GetLocalCertificate,
bool(const std::string& transport_name,

View File

@ -28,6 +28,7 @@
#include "pc/channel.h"
#include "pc/channelmanager.h"
#include "pc/mediasession.h"
#include "pc/peerconnection.h"
#include "pc/sctputils.h"
#include "pc/webrtcsessiondescriptionfactory.h"
#include "rtc_base/basictypes.h"
@ -390,26 +391,11 @@ static bool BadAnswerSdp(cricket::ContentSource source,
return BadSdp(source, SessionDescriptionInterface::kAnswer, reason, err_desc);
}
#define GET_STRING_OF_STATE(state) \
case webrtc::WebRtcSession::state: \
result = #state; \
break;
static std::string GetStateString(webrtc::WebRtcSession::State state) {
std::string result;
switch (state) {
GET_STRING_OF_STATE(STATE_INIT)
GET_STRING_OF_STATE(STATE_SENTOFFER)
GET_STRING_OF_STATE(STATE_RECEIVEDOFFER)
GET_STRING_OF_STATE(STATE_SENTPRANSWER)
GET_STRING_OF_STATE(STATE_RECEIVEDPRANSWER)
GET_STRING_OF_STATE(STATE_INPROGRESS)
GET_STRING_OF_STATE(STATE_CLOSED)
default:
RTC_NOTREACHED();
break;
}
return result;
static std::string BadStateErrMsg(
PeerConnectionInterface::SignalingState state) {
std::ostringstream desc;
desc << "Called in wrong state: " << GetSignalingStateString(state);
return desc.str();
}
#define GET_STRING_OF_ERROR_CODE(err) \
@ -474,41 +460,22 @@ bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc,
}
WebRtcSession::WebRtcSession(
Call* call,
cricket::ChannelManager* channel_manager,
const cricket::MediaConfig& media_config,
RtcEventLog* event_log,
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
cricket::PortAllocator* port_allocator,
PeerConnection* pc,
std::unique_ptr<cricket::TransportController> transport_controller,
std::unique_ptr<cricket::SctpTransportInternalFactory> sctp_factory)
: network_thread_(network_thread),
worker_thread_(worker_thread),
signaling_thread_(signaling_thread),
: pc_(pc),
// RFC 3264: The numeric value of the session id and version in the
// o line MUST be representable with a "64 bit signed integer".
// Due to this constraint session id |sid_| is max limited to LLONG_MAX.
sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
// Due to this constraint session id |session_id| is max limited to
// LLONG_MAX.
session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
transport_controller_(std::move(transport_controller)),
sctp_factory_(std::move(sctp_factory)),
media_config_(media_config),
event_log_(event_log),
call_(call),
channel_manager_(channel_manager),
ice_observer_(NULL),
ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
ice_connection_receiving_(true),
older_version_remote_peer_(false),
dtls_enabled_(false),
data_channel_type_(cricket::DCT_NONE),
metrics_observer_(NULL) {
data_channel_type_(cricket::DCT_NONE) {
transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
transport_controller_->SignalConnectionState.connect(
this, &WebRtcSession::OnTransportControllerConnectionState);
transport_controller_->SignalReceiving.connect(
this, &WebRtcSession::OnTransportControllerReceiving);
transport_controller_->SignalGatheringState.connect(
this, &WebRtcSession::OnTransportControllerGatheringState);
transport_controller_->SignalCandidatesGathered.connect(
@ -533,12 +500,12 @@ WebRtcSession::~WebRtcSession() {
DestroyDataChannel();
}
if (sctp_transport_) {
SignalDataChannelDestroyed();
network_thread_->Invoke<void>(
pc_->OnDataChannelDestroyed();
network_thread()->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&WebRtcSession::DestroySctpTransport_n, this));
}
LOG(LS_INFO) << "Session: " << id() << " is destroyed.";
LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
}
void WebRtcSession::Initialize(
@ -546,8 +513,6 @@ void WebRtcSession::Initialize(
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
const PeerConnectionInterface::RTCConfiguration& rtc_configuration,
PeerConnection* pc) {
bundle_policy_ = rtc_configuration.bundle_policy;
rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy;
transport_controller_->SetSslMaxProtocolVersion(options.ssl_max_version);
// Obtain a certificate from RTCConfiguration if any were provided (optional).
@ -607,8 +572,8 @@ void WebRtcSession::Initialize(
}
webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
signaling_thread(), channel_manager_, pc, id(), std::move(cert_generator),
certificate));
signaling_thread(), pc_->channel_manager(), pc, session_id(),
std::move(cert_generator), certificate));
webrtc_session_desc_factory_->SignalCertificateReady.connect(
this, &WebRtcSession::OnCertificateReady);
@ -621,9 +586,8 @@ void WebRtcSession::Initialize(
}
void WebRtcSession::Close() {
SetState(STATE_CLOSED);
pc_->ChangeSignalingState(PeerConnectionInterface::kClosed);
RemoveUnusedChannels(nullptr);
call_ = nullptr;
RTC_DCHECK(voice_channels_.empty());
RTC_DCHECK(video_channels_.empty());
RTC_DCHECK(!rtp_data_channel_);
@ -645,6 +609,16 @@ cricket::BaseChannel* WebRtcSession::GetChannel(
return nullptr;
}
rtc::Thread* WebRtcSession::network_thread() const {
return pc_->network_thread();
}
rtc::Thread* WebRtcSession::worker_thread() const {
return pc_->worker_thread();
}
rtc::Thread* WebRtcSession::signaling_thread() const {
return pc_->signaling_thread();
}
bool WebRtcSession::GetSctpSslRole(rtc::SSLRole* role) {
if (!local_description() || !remote_description()) {
LOG(LS_INFO) << "Local and Remote descriptions must be applied to get the "
@ -697,9 +671,13 @@ bool WebRtcSession::SetLocalDescription(
// Update the initial_offerer flag if this session is the initial_offerer.
Action action = GetAction(desc->type());
if (state() == STATE_INIT && action == kOffer) {
initial_offerer_ = true;
transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
if (!initial_offerer_.has_value()) {
initial_offerer_.emplace(action == kOffer);
if (*initial_offerer_) {
transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
} else {
transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
}
}
if (action == kAnswer) {
@ -833,8 +811,9 @@ bool WebRtcSession::SetRemoteDescription(
// read to determine the current checking state. The existing SignalConnecting
// actually means "gathering candidates", so cannot be be used here.
if (remote_description()->type() != SessionDescriptionInterface::kOffer &&
ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew) {
SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
pc_->ice_connection_state() ==
PeerConnectionInterface::kIceConnectionNew) {
pc_->SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
}
return true;
}
@ -849,28 +828,13 @@ std::vector<cricket::BaseChannel*> WebRtcSession::Channels() const {
channels.insert(channels.end(), video_channels_.begin(),
video_channels_.end());
if (rtp_data_channel_) {
channels.push_back(rtp_data_channel_.get());
channels.push_back(rtp_data_channel_);
}
return channels;
}
void WebRtcSession::LogState(State old_state, State new_state) {
LOG(LS_INFO) << "Session:" << id()
<< " Old state:" << GetStateString(old_state)
<< " New state:" << GetStateString(new_state);
}
void WebRtcSession::SetState(State state) {
RTC_DCHECK(signaling_thread_->IsCurrent());
if (state != state_) {
LogState(state_, state);
state_ = state;
SignalState(this, state_);
}
}
void WebRtcSession::SetError(Error error, const std::string& error_desc) {
RTC_DCHECK(signaling_thread_->IsCurrent());
RTC_DCHECK(signaling_thread()->IsCurrent());
if (error != error_) {
error_ = error;
error_desc_ = error_desc;
@ -890,8 +854,9 @@ bool WebRtcSession::UpdateSessionState(
if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) {
return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc);
}
SetState(source == cricket::CS_LOCAL ? STATE_SENTOFFER
: STATE_RECEIVEDOFFER);
pc_->ChangeSignalingState(source == cricket::CS_LOCAL
? PeerConnectionInterface::kHaveLocalOffer
: PeerConnectionInterface::kHaveRemoteOffer);
if (!PushdownMediaDescription(cricket::CA_OFFER, source, err_desc)) {
SetError(ERROR_CONTENT, *err_desc);
}
@ -903,8 +868,10 @@ bool WebRtcSession::UpdateSessionState(
return BadPranswerSdp(source, MakeTdErrorString(td_err), err_desc);
}
EnableChannels();
SetState(source == cricket::CS_LOCAL ? STATE_SENTPRANSWER
: STATE_RECEIVEDPRANSWER);
pc_->ChangeSignalingState(
source == cricket::CS_LOCAL
? PeerConnectionInterface::kHaveLocalPrAnswer
: PeerConnectionInterface::kHaveRemotePrAnswer);
if (!PushdownMediaDescription(cricket::CA_PRANSWER, source, err_desc)) {
SetError(ERROR_CONTENT, *err_desc);
}
@ -933,7 +900,7 @@ bool WebRtcSession::UpdateSessionState(
return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc);
}
EnableChannels();
SetState(STATE_INPROGRESS);
pc_->ChangeSignalingState(PeerConnectionInterface::kStable);
if (!PushdownMediaDescription(cricket::CA_ANSWER, source, err_desc)) {
SetError(ERROR_CONTENT, *err_desc);
}
@ -989,7 +956,7 @@ bool WebRtcSession::PushdownMediaDescription(
if (sctp_transport_ && local_description() && remote_description() &&
cricket::GetFirstDataContent(local_description()->description()) &&
cricket::GetFirstDataContent(remote_description()->description())) {
all_success &= network_thread_->Invoke<bool>(
all_success &= network_thread()->Invoke<bool>(
RTC_FROM_HERE,
rtc::Bind(&WebRtcSession::PushdownSctpParameters_n, this, source));
}
@ -997,7 +964,7 @@ bool WebRtcSession::PushdownMediaDescription(
}
bool WebRtcSession::PushdownSctpParameters_n(cricket::ContentSource source) {
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
RTC_DCHECK(local_description());
RTC_DCHECK(remote_description());
// Apply the SCTP port (which is hidden inside a DataCodec structure...)
@ -1133,7 +1100,7 @@ bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
RTC_DCHECK(sctp_content_name_);
if (transport_name != *sctp_transport_name_ &&
bundle.HasContentName(*sctp_content_name_)) {
network_thread_->Invoke<void>(
network_thread()->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&WebRtcSession::ChangeSctpTransport_n, this,
transport_name));
}
@ -1261,12 +1228,6 @@ bool WebRtcSession::GetRemoteTrackIdBySsrc(uint32_t ssrc,
track_id);
}
std::string WebRtcSession::BadStateErrMsg(State state) {
std::ostringstream desc;
desc << "Called in wrong state: " << GetStateString(state);
return desc.str();
}
bool WebRtcSession::SendData(const cricket::SendDataParams& params,
const rtc::CopyOnWriteBuffer& payload,
cricket::SendDataResult* result) {
@ -1277,7 +1238,7 @@ bool WebRtcSession::SendData(const cricket::SendDataParams& params,
}
return rtp_data_channel_
? rtp_data_channel_->SendData(params, payload, result)
: network_thread_->Invoke<bool>(
: network_thread()->Invoke<bool>(
RTC_FROM_HERE,
Bind(&cricket::SctpTransportInternal::SendData,
sctp_transport_.get(), params, payload, result));
@ -1327,7 +1288,7 @@ void WebRtcSession::AddSctpDataStream(int sid) {
LOG(LS_ERROR) << "AddSctpDataStream called when sctp_transport_ is NULL.";
return;
}
network_thread_->Invoke<void>(
network_thread()->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&cricket::SctpTransportInternal::OpenStream,
sctp_transport_.get(), sid));
}
@ -1338,7 +1299,7 @@ void WebRtcSession::RemoveSctpDataStream(int sid) {
<< "NULL.";
return;
}
network_thread_->Invoke<void>(
network_thread()->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&cricket::SctpTransportInternal::ResetStream,
sctp_transport_.get(), sid));
}
@ -1348,7 +1309,7 @@ bool WebRtcSession::ReadyToSendData() const {
sctp_ready_to_send_data_;
}
std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() {
std::unique_ptr<SessionStats> WebRtcSession::GetSessionStats_s() {
RTC_DCHECK(signaling_thread()->IsCurrent());
ChannelNamePairs channel_name_pairs;
if (voice_channel()) {
@ -1370,17 +1331,17 @@ std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() {
channel_name_pairs.data = rtc::Optional<ChannelNamePair>(
ChannelNamePair(*sctp_content_name_, *sctp_transport_name_));
}
return GetStats(channel_name_pairs);
return GetSessionStats(channel_name_pairs);
}
std::unique_ptr<SessionStats> WebRtcSession::GetStats(
std::unique_ptr<SessionStats> WebRtcSession::GetSessionStats(
const ChannelNamePairs& channel_name_pairs) {
if (network_thread()->IsCurrent()) {
return GetStats_n(channel_name_pairs);
return GetSessionStats_n(channel_name_pairs);
}
return network_thread()->Invoke<std::unique_ptr<SessionStats>>(
RTC_FROM_HERE,
rtc::Bind(&WebRtcSession::GetStats_n, this, channel_name_pairs));
rtc::Bind(&WebRtcSession::GetSessionStats_n, this, channel_name_pairs));
}
bool WebRtcSession::GetLocalCertificate(
@ -1422,31 +1383,6 @@ void WebRtcSession::OnDtlsSrtpSetupFailure(cricket::BaseChannel*, bool rtcp) {
rtcp ? kDtlsSrtpSetupFailureRtcp : kDtlsSrtpSetupFailureRtp);
}
bool WebRtcSession::waiting_for_certificate_for_testing() const {
return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
}
const rtc::scoped_refptr<rtc::RTCCertificate>&
WebRtcSession::certificate_for_testing() {
return transport_controller_->certificate_for_testing();
}
void WebRtcSession::SetIceConnectionState(
PeerConnectionInterface::IceConnectionState state) {
if (ice_connection_state_ == state) {
return;
}
LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
<< " => " << state;
RTC_DCHECK(ice_connection_state_ !=
PeerConnectionInterface::kIceConnectionClosed);
ice_connection_state_ = state;
if (ice_observer_) {
ice_observer_->OnIceConnectionStateChange(ice_connection_state_);
}
}
void WebRtcSession::OnTransportControllerConnectionState(
cricket::IceConnectionState state) {
switch (state) {
@ -1457,33 +1393,36 @@ void WebRtcSession::OnTransportControllerConnectionState(
// kIceConnectionConnecting is currently used as the default,
// un-connected state by the TransportController, so its only use is
// detecting disconnections.
if (ice_connection_state_ ==
if (pc_->ice_connection_state_ ==
PeerConnectionInterface::kIceConnectionConnected ||
ice_connection_state_ ==
pc_->ice_connection_state_ ==
PeerConnectionInterface::kIceConnectionCompleted) {
SetIceConnectionState(
pc_->SetIceConnectionState(
PeerConnectionInterface::kIceConnectionDisconnected);
}
break;
case cricket::kIceConnectionFailed:
SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
pc_->SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
break;
case cricket::kIceConnectionConnected:
LOG(LS_INFO) << "Changing to ICE connected state because "
<< "all transports are writable.";
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
pc_->SetIceConnectionState(
PeerConnectionInterface::kIceConnectionConnected);
break;
case cricket::kIceConnectionCompleted:
LOG(LS_INFO) << "Changing to ICE completed state because "
<< "all transports are complete.";
if (ice_connection_state_ !=
if (pc_->ice_connection_state_ !=
PeerConnectionInterface::kIceConnectionConnected) {
// If jumping directly from "checking" to "connected",
// signal "connected" first.
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
pc_->SetIceConnectionState(
PeerConnectionInterface::kIceConnectionConnected);
}
SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
if (metrics_observer_) {
pc_->SetIceConnectionState(
PeerConnectionInterface::kIceConnectionCompleted);
if (pc_->metrics_observer()) {
ReportTransportStats();
}
break;
@ -1492,20 +1431,6 @@ void WebRtcSession::OnTransportControllerConnectionState(
}
}
void WebRtcSession::OnTransportControllerReceiving(bool receiving) {
SetIceConnectionReceiving(receiving);
}
void WebRtcSession::SetIceConnectionReceiving(bool receiving) {
if (ice_connection_receiving_ == receiving) {
return;
}
ice_connection_receiving_ = receiving;
if (ice_observer_) {
ice_observer_->OnIceConnectionReceivingChange(receiving);
}
}
void WebRtcSession::OnTransportControllerCandidatesGathered(
const std::string& transport_name,
const cricket::Candidates& candidates) {
@ -1525,9 +1450,7 @@ void WebRtcSession::OnTransportControllerCandidatesGathered(
if (local_description()) {
mutable_local_description()->AddCandidate(candidate.get());
}
if (ice_observer_) {
ice_observer_->OnIceCandidate(std::move(candidate));
}
pc_->OnIceCandidate(std::move(candidate));
}
}
@ -1547,15 +1470,13 @@ void WebRtcSession::OnTransportControllerCandidatesRemoved(
if (local_description()) {
mutable_local_description()->RemoveCandidates(candidates);
}
if (ice_observer_) {
ice_observer_->OnIceCandidatesRemoved(candidates);
}
pc_->OnIceCandidatesRemoved(candidates);
}
void WebRtcSession::OnTransportControllerDtlsHandshakeError(
rtc::SSLHandshakeError error) {
if (metrics_observer_) {
metrics_observer_->IncrementEnumCounter(
if (pc_->metrics_observer()) {
pc_->metrics_observer()->IncrementEnumCounter(
webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error),
static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
}
@ -1644,8 +1565,9 @@ bool WebRtcSession::UseCandidate(const IceCandidateInterface* candidate) {
if (transport_controller_->AddRemoteCandidates(content.name, candidates,
&error)) {
// Candidates successfully submitted for checking.
if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
ice_connection_state_ ==
if (pc_->ice_connection_state_ ==
PeerConnectionInterface::kIceConnectionNew ||
pc_->ice_connection_state_ ==
PeerConnectionInterface::kIceConnectionDisconnected) {
// If state is New, then the session has just gotten its first remote ICE
// candidates, so go to Checking.
@ -1655,7 +1577,8 @@ bool WebRtcSession::UseCandidate(const IceCandidateInterface* candidate) {
// TODO(bemasc): If state is Connected, and the new candidates are for a
// newly added transport, then the state actually _should_ move to
// checking. Add a way to distinguish that case.
SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
pc_->SetIceConnectionState(
PeerConnectionInterface::kIceConnectionChecking);
}
// TODO(bemasc): If state is Completed, go back to Connected.
} else {
@ -1687,8 +1610,8 @@ void WebRtcSession::RemoveUnusedChannels(const SessionDescription* desc) {
DestroyDataChannel();
}
if (sctp_transport_) {
SignalDataChannelDestroyed();
network_thread_->Invoke<void>(
pc_->OnDataChannelDestroyed();
network_thread()->Invoke<void>(
RTC_FROM_HERE,
rtc::Bind(&WebRtcSession::DestroySctpTransport_n, this));
}
@ -1719,7 +1642,8 @@ const std::string* WebRtcSession::GetBundleTransportName(
bool WebRtcSession::CreateChannels(const SessionDescription* desc) {
// TODO(steveanton): Add support for multiple audio/video channels.
const cricket::ContentGroup* bundle_group = nullptr;
if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) {
if (pc_->configuration_.bundle_policy ==
PeerConnectionInterface::kBundlePolicyMaxBundle) {
bundle_group = desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
if (!bundle_group) {
LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified";
@ -1763,9 +1687,6 @@ bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content,
// channels.
RTC_DCHECK(voice_channels_.empty());
bool require_rtcp_mux =
rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire;
std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
@ -1773,15 +1694,18 @@ bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content,
transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
if (!require_rtcp_mux) {
if (pc_->configuration_.rtcp_mux_policy !=
PeerConnectionInterface::kRtcpMuxPolicyRequire) {
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
}
cricket::VoiceChannel* voice_channel = channel_manager_->CreateVoiceChannel(
call_, media_config_, rtp_dtls_transport, rtcp_dtls_transport,
transport_controller_->signaling_thread(), content->name, SrtpRequired(),
audio_options_);
cricket::VoiceChannel* voice_channel =
pc_->channel_manager()->CreateVoiceChannel(
pc_->call_.get(), pc_->configuration_.media_config,
rtp_dtls_transport, rtcp_dtls_transport,
transport_controller_->signaling_thread(), content->name,
SrtpRequired(), audio_options_);
if (!voice_channel) {
transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
@ -1801,7 +1725,7 @@ bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content,
// TODO(steveanton): This should signal which voice channel was created since
// we can have multiple.
SignalVoiceChannelCreated();
pc_->OnVoiceChannelCreated();
voice_channel->SignalSentPacket.connect(this, &WebRtcSession::OnSentPacket_w);
return true;
}
@ -1812,9 +1736,6 @@ bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content,
// channels.
RTC_DCHECK(video_channels_.empty());
bool require_rtcp_mux =
rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire;
std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
@ -1822,15 +1743,18 @@ bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content,
transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
if (!require_rtcp_mux) {
if (pc_->configuration_.rtcp_mux_policy !=
PeerConnectionInterface::kRtcpMuxPolicyRequire) {
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
}
cricket::VideoChannel* video_channel = channel_manager_->CreateVideoChannel(
call_, media_config_, rtp_dtls_transport, rtcp_dtls_transport,
transport_controller_->signaling_thread(), content->name, SrtpRequired(),
video_options_);
cricket::VideoChannel* video_channel =
pc_->channel_manager()->CreateVideoChannel(
pc_->call_.get(), pc_->configuration_.media_config,
rtp_dtls_transport, rtcp_dtls_transport,
transport_controller_->signaling_thread(), content->name,
SrtpRequired(), video_options_);
if (!video_channel) {
transport_controller_->DestroyDtlsTransport(
@ -1851,7 +1775,7 @@ bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content,
// TODO(steveanton): This should signal which video channel was created since
// we can have multiple.
SignalVideoChannelCreated();
pc_->OnVideoChannelCreated();
video_channel->SignalSentPacket.connect(this, &WebRtcSession::OnSentPacket_w);
return true;
}
@ -1868,30 +1792,28 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content,
"SCTP support (HAVE_SCTP)";
return false;
}
if (!network_thread_->Invoke<bool>(
if (!network_thread()->Invoke<bool>(
RTC_FROM_HERE, rtc::Bind(&WebRtcSession::CreateSctpTransport_n,
this, content->name, transport_name))) {
return false;
}
} else {
bool require_rtcp_mux =
rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire;
std::string transport_name =
bundle_transport ? *bundle_transport : content->name;
cricket::DtlsTransportInternal* rtp_dtls_transport =
transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
if (!require_rtcp_mux) {
if (pc_->configuration_.rtcp_mux_policy !=
PeerConnectionInterface::kRtcpMuxPolicyRequire) {
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
}
rtp_data_channel_.reset(channel_manager_->CreateRtpDataChannel(
media_config_, rtp_dtls_transport, rtcp_dtls_transport,
transport_controller_->signaling_thread(), content->name,
SrtpRequired()));
rtp_data_channel_ = pc_->channel_manager()->CreateRtpDataChannel(
pc_->configuration_.media_config, rtp_dtls_transport,
rtcp_dtls_transport, transport_controller_->signaling_thread(),
content->name, SrtpRequired());
if (!rtp_data_channel_) {
transport_controller_->DestroyDtlsTransport(
@ -1911,7 +1833,7 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content,
&WebRtcSession::OnSentPacket_w);
}
SignalDataChannelCreated();
pc_->OnDataChannelCreated();
return true;
}
@ -1921,12 +1843,14 @@ Call::Stats WebRtcSession::GetCallStats() {
return worker_thread()->Invoke<Call::Stats>(
RTC_FROM_HERE, rtc::Bind(&WebRtcSession::GetCallStats, this));
}
if (!call_)
if (pc_->call_) {
return pc_->call_->GetStats();
} else {
return Call::Stats();
return call_->GetStats();
}
}
std::unique_ptr<SessionStats> WebRtcSession::GetStats_n(
std::unique_ptr<SessionStats> WebRtcSession::GetSessionStats_n(
const ChannelNamePairs& channel_name_pairs) {
RTC_DCHECK(network_thread()->IsCurrent());
std::unique_ptr<SessionStats> session_stats(new SessionStats());
@ -1950,7 +1874,7 @@ std::unique_ptr<SessionStats> WebRtcSession::GetStats_n(
bool WebRtcSession::CreateSctpTransport_n(const std::string& content_name,
const std::string& transport_name) {
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
RTC_DCHECK(sctp_factory_);
cricket::DtlsTransportInternal* tc =
transport_controller_->CreateDtlsTransport_n(
@ -1970,7 +1894,7 @@ bool WebRtcSession::CreateSctpTransport_n(const std::string& content_name,
}
void WebRtcSession::ChangeSctpTransport_n(const std::string& transport_name) {
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
RTC_DCHECK(sctp_transport_);
RTC_DCHECK(sctp_transport_name_);
std::string old_sctp_transport_name = *sctp_transport_name_;
@ -1984,7 +1908,7 @@ void WebRtcSession::ChangeSctpTransport_n(const std::string& transport_name) {
}
void WebRtcSession::DestroySctpTransport_n() {
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
sctp_transport_.reset(nullptr);
sctp_content_name_.reset();
sctp_transport_name_.reset();
@ -1994,14 +1918,14 @@ void WebRtcSession::DestroySctpTransport_n() {
void WebRtcSession::OnSctpTransportReadyToSendData_n() {
RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP);
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
sctp_invoker_->AsyncInvoke<void>(
RTC_FROM_HERE, signaling_thread_,
RTC_FROM_HERE, signaling_thread(),
rtc::Bind(&WebRtcSession::OnSctpTransportReadyToSendData_s, this, true));
}
void WebRtcSession::OnSctpTransportReadyToSendData_s(bool ready) {
RTC_DCHECK(signaling_thread_->IsCurrent());
RTC_DCHECK(signaling_thread()->IsCurrent());
sctp_ready_to_send_data_ = ready;
SignalSctpReadyToSendData(ready);
}
@ -2010,9 +1934,9 @@ void WebRtcSession::OnSctpTransportDataReceived_n(
const cricket::ReceiveDataParams& params,
const rtc::CopyOnWriteBuffer& payload) {
RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP);
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
sctp_invoker_->AsyncInvoke<void>(
RTC_FROM_HERE, signaling_thread_,
RTC_FROM_HERE, signaling_thread(),
rtc::Bind(&WebRtcSession::OnSctpTransportDataReceived_s, this, params,
payload));
}
@ -2020,7 +1944,7 @@ void WebRtcSession::OnSctpTransportDataReceived_n(
void WebRtcSession::OnSctpTransportDataReceived_s(
const cricket::ReceiveDataParams& params,
const rtc::CopyOnWriteBuffer& payload) {
RTC_DCHECK(signaling_thread_->IsCurrent());
RTC_DCHECK(signaling_thread()->IsCurrent());
if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) {
// Received OPEN message; parse and signal that a new data channel should
// be created.
@ -2033,7 +1957,7 @@ void WebRtcSession::OnSctpTransportDataReceived_s(
return;
}
config.open_handshake_role = InternalDataChannelInit::kAcker;
SignalDataChannelOpenMessage(label, config);
pc_->OnDataChannelOpenMessage(label, config);
} else {
// Otherwise just forward the signal.
SignalSctpDataReceived(params, payload);
@ -2042,9 +1966,9 @@ void WebRtcSession::OnSctpTransportDataReceived_s(
void WebRtcSession::OnSctpStreamClosedRemotely_n(int sid) {
RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP);
RTC_DCHECK(network_thread_->IsCurrent());
RTC_DCHECK(network_thread()->IsCurrent());
sctp_invoker_->AsyncInvoke<void>(
RTC_FROM_HERE, signaling_thread_,
RTC_FROM_HERE, signaling_thread(),
rtc::Bind(&sigslot::signal1<int>::operator(),
&SignalSctpStreamClosedRemotely, sid));
}
@ -2097,10 +2021,12 @@ bool WebRtcSession::ValidateSessionDescription(
Action action = GetAction(sdesc->type());
if (source == cricket::CS_LOCAL) {
if (!ExpectSetLocalDescription(action))
return BadLocalSdp(type, BadStateErrMsg(state()), err_desc);
return BadLocalSdp(type, BadStateErrMsg(pc_->signaling_state()),
err_desc);
} else {
if (!ExpectSetRemoteDescription(action))
return BadRemoteSdp(type, BadStateErrMsg(state()), err_desc);
return BadRemoteSdp(type, BadStateErrMsg(pc_->signaling_state()),
err_desc);
}
// Verify crypto settings.
@ -2151,29 +2077,25 @@ bool WebRtcSession::ValidateSessionDescription(
}
bool WebRtcSession::ExpectSetLocalDescription(Action action) {
return ((action == kOffer && state() == STATE_INIT) ||
// update local offer
(action == kOffer && state() == STATE_SENTOFFER) ||
// update the current ongoing session.
(action == kOffer && state() == STATE_INPROGRESS) ||
// accept remote offer
(action == kAnswer && state() == STATE_RECEIVEDOFFER) ||
(action == kAnswer && state() == STATE_SENTPRANSWER) ||
(action == kPrAnswer && state() == STATE_RECEIVEDOFFER) ||
(action == kPrAnswer && state() == STATE_SENTPRANSWER));
PeerConnectionInterface::SignalingState state = pc_->signaling_state();
if (action == kOffer) {
return (state == PeerConnectionInterface::kStable) ||
(state == PeerConnectionInterface::kHaveLocalOffer);
} else { // Answer or PrAnswer
return (state == PeerConnectionInterface::kHaveRemoteOffer) ||
(state == PeerConnectionInterface::kHaveLocalPrAnswer);
}
}
bool WebRtcSession::ExpectSetRemoteDescription(Action action) {
return ((action == kOffer && state() == STATE_INIT) ||
// update remote offer
(action == kOffer && state() == STATE_RECEIVEDOFFER) ||
// update the current ongoing session
(action == kOffer && state() == STATE_INPROGRESS) ||
// accept local offer
(action == kAnswer && state() == STATE_SENTOFFER) ||
(action == kAnswer && state() == STATE_RECEIVEDPRANSWER) ||
(action == kPrAnswer && state() == STATE_SENTOFFER) ||
(action == kPrAnswer && state() == STATE_RECEIVEDPRANSWER));
PeerConnectionInterface::SignalingState state = pc_->signaling_state();
if (action == kOffer) {
return (state == PeerConnectionInterface::kStable) ||
(state == PeerConnectionInterface::kHaveRemoteOffer);
} else { // Answer or PrAnswer.
return (state == PeerConnectionInterface::kHaveLocalOffer) ||
(state == PeerConnectionInterface::kHaveRemotePrAnswer);
}
}
std::string WebRtcSession::GetSessionErrorMsg() {
@ -2232,15 +2154,9 @@ void WebRtcSession::OnTransportControllerGatheringState(
cricket::IceGatheringState state) {
RTC_DCHECK(signaling_thread()->IsCurrent());
if (state == cricket::kIceGatheringGathering) {
if (ice_observer_) {
ice_observer_->OnIceGatheringChange(
PeerConnectionInterface::kIceGatheringGathering);
}
pc_->OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
} else if (state == cricket::kIceGatheringComplete) {
if (ice_observer_) {
ice_observer_->OnIceGatheringChange(
PeerConnectionInterface::kIceGatheringComplete);
}
pc_->OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
}
}
@ -2272,7 +2188,7 @@ void WebRtcSession::ReportTransportStats() {
// for IPv4 and IPv6.
void WebRtcSession::ReportBestConnectionState(
const cricket::TransportStats& stats) {
RTC_DCHECK(metrics_observer_ != NULL);
RTC_DCHECK(pc_->metrics_observer());
for (cricket::TransportChannelStatsList::const_iterator it =
stats.channel_stats.begin();
it != stats.channel_stats.end(); ++it) {
@ -2297,18 +2213,18 @@ void WebRtcSession::ReportBestConnectionState(
} else {
RTC_CHECK(0);
}
metrics_observer_->IncrementEnumCounter(
pc_->metrics_observer()->IncrementEnumCounter(
type, GetIceCandidatePairCounter(local, remote),
kIceCandidatePairMax);
// Increment the counter for IP type.
if (local.address().family() == AF_INET) {
metrics_observer_->IncrementEnumCounter(
pc_->metrics_observer()->IncrementEnumCounter(
kEnumCounterAddressFamily, kBestConnections_IPv4,
kPeerConnectionAddressFamilyCounter_Max);
} else if (local.address().family() == AF_INET6) {
metrics_observer_->IncrementEnumCounter(
pc_->metrics_observer()->IncrementEnumCounter(
kEnumCounterAddressFamily, kBestConnections_IPv6,
kPeerConnectionAddressFamilyCounter_Max);
} else {
@ -2322,7 +2238,7 @@ void WebRtcSession::ReportBestConnectionState(
void WebRtcSession::ReportNegotiatedCiphers(
const cricket::TransportStats& stats) {
RTC_DCHECK(metrics_observer_ != NULL);
RTC_DCHECK(pc_->metrics_observer());
if (!dtls_enabled_ || stats.channel_stats.empty()) {
return;
}
@ -2351,19 +2267,19 @@ void WebRtcSession::ReportNegotiatedCiphers(
}
if (srtp_crypto_suite != rtc::SRTP_INVALID_CRYPTO_SUITE) {
metrics_observer_->IncrementSparseEnumCounter(srtp_counter_type,
srtp_crypto_suite);
pc_->metrics_observer()->IncrementSparseEnumCounter(srtp_counter_type,
srtp_crypto_suite);
}
if (ssl_cipher_suite != rtc::TLS_NULL_WITH_NULL_NULL) {
metrics_observer_->IncrementSparseEnumCounter(ssl_counter_type,
ssl_cipher_suite);
pc_->metrics_observer()->IncrementSparseEnumCounter(ssl_counter_type,
ssl_cipher_suite);
}
}
void WebRtcSession::OnSentPacket_w(const rtc::SentPacket& sent_packet) {
RTC_DCHECK(worker_thread()->IsCurrent());
RTC_DCHECK(call_);
call_->OnSentPacket(sent_packet);
RTC_DCHECK(pc_->call_);
pc_->call_->OnSentPacket(sent_packet);
}
const std::string WebRtcSession::GetTransportName(
@ -2404,7 +2320,7 @@ void WebRtcSession::RemoveAndDestroyVideoChannel(
void WebRtcSession::DestroyVideoChannel(cricket::VideoChannel* video_channel) {
// TODO(steveanton): This should take an identifier for the video channel
// since we now support more than one.
SignalVideoChannelDestroyed();
pc_->OnVideoChannelDestroyed();
RTC_DCHECK(video_channel->rtp_dtls_transport());
const std::string transport_name =
video_channel->rtp_dtls_transport()->transport_name();
@ -2412,7 +2328,7 @@ void WebRtcSession::DestroyVideoChannel(cricket::VideoChannel* video_channel) {
(video_channel->rtcp_dtls_transport() != nullptr);
// The above need to be cached before destroying the video channel so that we
// do not access uninitialized memory.
channel_manager_->DestroyVideoChannel(video_channel);
pc_->channel_manager()->DestroyVideoChannel(video_channel);
transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
if (need_to_delete_rtcp) {
@ -2436,7 +2352,7 @@ void WebRtcSession::RemoveAndDestroyVoiceChannel(
void WebRtcSession::DestroyVoiceChannel(cricket::VoiceChannel* voice_channel) {
// TODO(steveanton): This should take an identifier for the voice channel
// since we now support more than one.
SignalVoiceChannelDestroyed();
pc_->OnVoiceChannelDestroyed();
RTC_DCHECK(voice_channel->rtp_dtls_transport());
const std::string transport_name =
voice_channel->rtp_dtls_transport()->transport_name();
@ -2444,7 +2360,7 @@ void WebRtcSession::DestroyVoiceChannel(cricket::VoiceChannel* voice_channel) {
(voice_channel->rtcp_dtls_transport() != nullptr);
// The above need to be cached before destroying the video channel so that we
// do not access uninitialized memory.
channel_manager_->DestroyVoiceChannel(voice_channel);
pc_->channel_manager()->DestroyVoiceChannel(voice_channel);
transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
if (need_to_delete_rtcp) {
@ -2454,13 +2370,14 @@ void WebRtcSession::DestroyVoiceChannel(cricket::VoiceChannel* voice_channel) {
}
void WebRtcSession::DestroyDataChannel() {
SignalDataChannelDestroyed();
pc_->OnDataChannelDestroyed();
RTC_DCHECK(rtp_data_channel_->rtp_dtls_transport());
std::string transport_name;
transport_name = rtp_data_channel_->rtp_dtls_transport()->transport_name();
bool need_to_delete_rtcp =
(rtp_data_channel_->rtcp_dtls_transport() != nullptr);
channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release());
pc_->channel_manager()->DestroyRtpDataChannel(rtp_data_channel_);
rtp_data_channel_ = nullptr;
transport_controller_->DestroyDtlsTransport(
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
if (need_to_delete_rtcp) {

View File

@ -51,55 +51,6 @@ class PeerConnection;
class RtcEventLog;
class WebRtcSessionDescriptionFactory;
extern const char kBundleWithoutRtcpMux[];
extern const char kCreateChannelFailed[];
extern const char kInvalidCandidates[];
extern const char kInvalidSdp[];
extern const char kMlineMismatchInAnswer[];
extern const char kMlineMismatchInSubsequentOffer[];
extern const char kPushDownTDFailed[];
extern const char kSdpWithoutDtlsFingerprint[];
extern const char kSdpWithoutSdesCrypto[];
extern const char kSdpWithoutIceUfragPwd[];
extern const char kSdpWithoutSdesAndDtlsDisabled[];
extern const char kSessionError[];
extern const char kSessionErrorDesc[];
extern const char kDtlsSrtpSetupFailureRtp[];
extern const char kDtlsSrtpSetupFailureRtcp[];
extern const char kEnableBundleFailed[];
// Maximum number of received video streams that will be processed by webrtc
// even if they are not signalled beforehand.
extern const int kMaxUnsignalledRecvStreams;
// ICE state callback interface.
class IceObserver {
public:
IceObserver() {}
// Called any time the IceConnectionState changes
virtual void OnIceConnectionStateChange(
PeerConnectionInterface::IceConnectionState new_state) {}
// Called any time the IceGatheringState changes
virtual void OnIceGatheringChange(
PeerConnectionInterface::IceGatheringState new_state) {}
// New Ice candidate have been found.
virtual void OnIceCandidate(
std::unique_ptr<IceCandidateInterface> candidate) = 0;
// Some local ICE candidates have been removed.
virtual void OnIceCandidatesRemoved(
const std::vector<cricket::Candidate>& candidates) = 0;
// Called whenever the state changes between receiving and not receiving.
virtual void OnIceConnectionReceivingChange(bool receiving) {}
protected:
~IceObserver() {}
private:
RTC_DISALLOW_COPY_AND_ASSIGN(IceObserver);
};
// Statistics for all the transports of the session.
// TODO(pthatcher): Think of a better name for this. We already have
// a TransportStats in transport.h. Perhaps TransportsStats?
@ -133,16 +84,6 @@ class WebRtcSession :
public DataChannelProviderInterface,
public sigslot::has_slots<> {
public:
enum State {
STATE_INIT = 0,
STATE_SENTOFFER, // Sent offer, waiting for answer.
STATE_RECEIVEDOFFER, // Received an offer. Need to send answer.
STATE_SENTPRANSWER, // Sent provisional answer. Need to send answer.
STATE_RECEIVEDPRANSWER, // Received provisional answer, waiting for answer.
STATE_INPROGRESS, // Offer/answer exchange completed.
STATE_CLOSED, // Close() was called.
};
enum Error {
ERROR_NONE = 0, // no error
ERROR_CONTENT = 1, // channel errors in SetLocalContent/SetRemoteContent
@ -151,25 +92,18 @@ class WebRtcSession :
// |sctp_factory| may be null, in which case SCTP is treated as unsupported.
WebRtcSession(
Call* call,
cricket::ChannelManager* channel_manager,
const cricket::MediaConfig& media_config,
RtcEventLog* event_log,
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
cricket::PortAllocator* port_allocator,
PeerConnection* pc, // TODO(steveanton): Temporary.
std::unique_ptr<cricket::TransportController> transport_controller,
std::unique_ptr<cricket::SctpTransportInternalFactory> sctp_factory);
virtual ~WebRtcSession();
// These are const to allow them to be called from const methods.
rtc::Thread* network_thread() const { return network_thread_; }
rtc::Thread* worker_thread() const { return worker_thread_; }
rtc::Thread* signaling_thread() const { return signaling_thread_; }
rtc::Thread* network_thread() const;
rtc::Thread* worker_thread() const;
rtc::Thread* signaling_thread() const;
// The ID of this session.
const std::string& id() const { return sid_; }
const std::string& session_id() const { return session_id_; }
void Initialize(
const PeerConnectionFactoryInterface::Options& options,
@ -181,21 +115,12 @@ class WebRtcSession :
void Close();
// Returns true if we were the initial offerer.
bool initial_offerer() const { return initial_offerer_; }
// Returns the current state of the session. See the enum above for details.
// Each time the state changes, we will fire this signal.
State state() const { return state_; }
sigslot::signal2<WebRtcSession*, State> SignalState;
bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
// Returns the last error in the session. See the enum above for details.
Error error() const { return error_; }
const std::string& error_desc() const { return error_desc_; }
void RegisterIceObserver(IceObserver* observer) {
ice_observer_ = observer;
}
// Exposed for stats collecting.
// TODO(steveanton): Switch callers to use the plural form and remove these.
virtual cricket::VoiceChannel* voice_channel() {
@ -222,7 +147,7 @@ class WebRtcSession :
// Only valid when using deprecated RTP data channels.
virtual cricket::RtpDataChannel* rtp_data_channel() {
return rtp_data_channel_.get();
return rtp_data_channel_;
}
virtual rtc::Optional<std::string> sctp_content_name() const {
return sctp_content_name_;
@ -309,8 +234,8 @@ class WebRtcSession :
// called on the signaling thread - and invokes the other |GetStats|. The
// other |GetStats| can be invoked on any thread; if not invoked on the
// network thread a thread hop will happen.
std::unique_ptr<SessionStats> GetStats_s();
virtual std::unique_ptr<SessionStats> GetStats(
std::unique_ptr<SessionStats> GetSessionStats_s();
virtual std::unique_ptr<SessionStats> GetSessionStats(
const ChannelNamePairs& channel_name_pairs);
// virtual so it can be mocked in unit tests
@ -343,31 +268,10 @@ class WebRtcSession :
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
void OnDtlsSrtpSetupFailure(cricket::BaseChannel*, bool rtcp);
// For unit test.
bool waiting_for_certificate_for_testing() const;
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate_for_testing();
void set_metrics_observer(
webrtc::MetricsObserverInterface* metrics_observer) {
metrics_observer_ = metrics_observer;
transport_controller_->SetMetricsObserver(metrics_observer);
cricket::TransportController* transport_controller() const {
return transport_controller_.get();
}
// Called when voice_channel_, video_channel_ and
// rtp_data_channel_/sctp_transport_ are created and destroyed. As a result
// of, for example, setting a new description.
sigslot::signal0<> SignalVoiceChannelCreated;
sigslot::signal0<> SignalVoiceChannelDestroyed;
sigslot::signal0<> SignalVideoChannelCreated;
sigslot::signal0<> SignalVideoChannelDestroyed;
sigslot::signal0<> SignalDataChannelCreated;
sigslot::signal0<> SignalDataChannelDestroyed;
// Called when a valid data channel OPEN message is received.
// std::string represents the data channel label.
sigslot::signal2<const std::string&, const InternalDataChannelInit&>
SignalDataChannelOpenMessage;
private:
// Indicates the type of SessionDescription in a call to SetLocalDescription
// and SetRemoteDescription.
@ -377,6 +281,11 @@ class WebRtcSession :
kAnswer,
};
// TODO(steveanton): Remove this once WebRtcSession and PeerConnection are
// merged. This is so that we can eliminate signals from this class and
// directly call the method in PeerConnection they are connected to.
PeerConnection* pc_;
// Return all managed, non-null channels.
std::vector<cricket::BaseChannel*> Channels() const;
@ -391,19 +300,12 @@ class WebRtcSession :
: current_remote_description_.get();
}
// Log session state.
void LogState(State old_state, State new_state);
// Updates the state, signaling if necessary.
virtual void SetState(State state);
// Updates the error state, signaling if necessary.
// TODO(ronghuawu): remove the SetError method that doesn't take |error_desc|.
virtual void SetError(Error error, const std::string& error_desc);
void SetError(Error error, const std::string& error_desc);
bool UpdateSessionState(Action action, cricket::ContentSource source,
std::string* err_desc);
static Action GetAction(const std::string& type);
Action GetAction(const std::string& type);
// Push the media parts of the local or remote session description
// down to all of the channels.
bool PushdownMediaDescription(cricket::ContentAction action,
@ -471,7 +373,7 @@ class WebRtcSession :
bool CreateDataChannel(const cricket::ContentInfo* content,
const std::string* bundle_transport);
std::unique_ptr<SessionStats> GetStats_n(
std::unique_ptr<SessionStats> GetSessionStats_n(
const ChannelNamePairs& channel_name_pairs);
bool CreateSctpTransport_n(const std::string& content_name,
@ -493,10 +395,6 @@ class WebRtcSession :
const rtc::CopyOnWriteBuffer& payload);
void OnSctpStreamClosedRemotely_n(int sid);
std::string BadStateErrMsg(State state);
void SetIceConnectionState(PeerConnectionInterface::IceConnectionState state);
void SetIceConnectionReceiving(bool receiving);
bool ValidateBundleSettings(const cricket::SessionDescription* desc);
bool HasRtcpMuxEnabled(const cricket::ContentInfo* content);
// Below methods are helper methods which verifies SDP.
@ -526,7 +424,6 @@ class WebRtcSession :
// TransportController signal handlers.
void OnTransportControllerConnectionState(cricket::IceConnectionState state);
void OnTransportControllerReceiving(bool receiving);
void OnTransportControllerGatheringState(cricket::IceGatheringState state);
void OnTransportControllerCandidatesGathered(
const std::string& transport_name,
@ -557,22 +454,14 @@ class WebRtcSession :
void DestroyVoiceChannel(cricket::VoiceChannel* voice_channel);
void DestroyDataChannel();
rtc::Thread* const network_thread_;
rtc::Thread* const worker_thread_;
rtc::Thread* const signaling_thread_;
State state_ = STATE_INIT;
Error error_ = ERROR_NONE;
std::string error_desc_;
const std::string sid_;
bool initial_offerer_ = false;
const std::string session_id_;
rtc::Optional<bool> initial_offerer_;
const std::unique_ptr<cricket::TransportController> transport_controller_;
const std::unique_ptr<cricket::SctpTransportInternalFactory> sctp_factory_;
const cricket::MediaConfig media_config_;
RtcEventLog* event_log_;
Call* call_;
// TODO(steveanton): voice_channels_ and video_channels_ used to be a single
// VoiceChannel/VideoChannel respectively but are being changed to support
// multiple m= lines in unified plan. But until more work is done, these can
@ -582,10 +471,7 @@ class WebRtcSession :
std::vector<cricket::VideoChannel*> video_channels_;
// |rtp_data_channel_| is used if in RTP data channel mode, |sctp_transport_|
// when using SCTP.
// TODO(steveanton): This should be changed to a bare pointer because
// WebRtcSession doesn't actually own the RtpDataChannel
// (ChannelManager does).
std::unique_ptr<cricket::RtpDataChannel> rtp_data_channel_;
cricket::RtpDataChannel* rtp_data_channel_ = nullptr;
std::unique_ptr<cricket::SctpTransportInternal> sctp_transport_;
// |sctp_transport_name_| keeps track of what DTLS transport the SCTP
@ -612,16 +498,10 @@ class WebRtcSession :
SignalSctpDataReceived;
sigslot::signal1<int> SignalSctpStreamClosedRemotely;
cricket::ChannelManager* channel_manager_;
IceObserver* ice_observer_;
PeerConnectionInterface::IceConnectionState ice_connection_state_;
bool ice_connection_receiving_;
std::unique_ptr<SessionDescriptionInterface> current_local_description_;
std::unique_ptr<SessionDescriptionInterface> pending_local_description_;
std::unique_ptr<SessionDescriptionInterface> current_remote_description_;
std::unique_ptr<SessionDescriptionInterface> pending_remote_description_;
// If the remote peer is using a older version of implementation.
bool older_version_remote_peer_;
bool dtls_enabled_;
// Specifies which kind of data channel is allowed. This is controlled
// by the chrome command-line flag and constraints:
@ -639,16 +519,6 @@ class WebRtcSession :
// Member variables for caching global options.
cricket::AudioOptions audio_options_;
cricket::VideoOptions video_options_;
MetricsObserverInterface* metrics_observer_;
// Declares the bundle policy for the WebRTCSession.
PeerConnectionInterface::BundlePolicy bundle_policy_;
// Declares the RTCP mux policy for the WebRTCSession.
PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy_;
bool received_first_video_packet_ = false;
bool received_first_audio_packet_ = false;
RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcSession);
};