Move from BaseSession::GetStats to WebRtcSession::GetTransportStats

This is a part of the big BUNDLE implementation at https://webrtc-codereview.appspot.com/45519004/

Review URL: https://webrtc-codereview.appspot.com/45639004

Cr-Commit-Position: refs/heads/master@{#8739}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8739 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pthatcher@webrtc.org 2015-03-16 19:31:40 +00:00
parent aba9219e5c
commit c04a97f054
7 changed files with 128 additions and 109 deletions

View File

@ -161,6 +161,11 @@ public class PeerConnectionTest {
return;
}
if (expectedIceConnectionChanges.isEmpty()) {
System.out.println(name + "Got an unexpected ice connection change " + newState);
return;
}
assertEquals(expectedIceConnectionChanges.removeFirst(), newState);
}

View File

@ -667,80 +667,82 @@ void StatsCollector::ExtractSessionInfo() {
session_->initiator());
cricket::SessionStats stats;
if (session_->GetStats(&stats)) {
// Store the proxy map away for use in SSRC reporting.
// TODO(tommi): This shouldn't be necessary if we post the stats back to the
// signaling thread after fetching them on the worker thread, then just use
// the proxy map directly from the session stats.
// As is, if GetStats() failed, we could be using old (incorrect?) proxy
// data.
proxy_to_transport_ = stats.proxy_to_transport;
if (!session_->GetTransportStats(&stats)) {
return;
}
for (const auto& transport_iter : stats.transport_stats) {
// Attempt to get a copy of the certificates from the transport and
// expose them in stats reports. All channels in a transport share the
// same local and remote certificates.
//
// Note that Transport::GetIdentity and Transport::GetRemoteCertificate
// invoke method calls on the worker thread and block this thread, but
// messages are still processed on this thread, which may blow way the
// existing transports. So we cannot reuse |transport| after these calls.
StatsReport::Id local_cert_report_id, remote_cert_report_id;
// Store the proxy map away for use in SSRC reporting.
// TODO(tommi): This shouldn't be necessary if we post the stats back to the
// signaling thread after fetching them on the worker thread, then just use
// the proxy map directly from the session stats.
// As is, if GetStats() failed, we could be using old (incorrect?) proxy
// data.
proxy_to_transport_ = stats.proxy_to_transport;
cricket::Transport* transport =
session_->GetTransport(transport_iter.second.content_name);
rtc::scoped_ptr<rtc::SSLIdentity> identity;
if (transport && transport->GetIdentity(identity.accept())) {
StatsReport* r = AddCertificateReports(&(identity->certificate()));
if (r)
local_cert_report_id = r->id();
for (const auto& transport_iter : stats.transport_stats) {
// Attempt to get a copy of the certificates from the transport and
// expose them in stats reports. All channels in a transport share the
// same local and remote certificates.
//
// Note that Transport::GetIdentity and Transport::GetRemoteCertificate
// invoke method calls on the worker thread and block this thread, but
// messages are still processed on this thread, which may blow way the
// existing transports. So we cannot reuse |transport| after these calls.
StatsReport::Id local_cert_report_id, remote_cert_report_id;
cricket::Transport* transport =
session_->GetTransport(transport_iter.second.content_name);
rtc::scoped_ptr<rtc::SSLIdentity> identity;
if (transport && transport->GetIdentity(identity.accept())) {
StatsReport* r = AddCertificateReports(&(identity->certificate()));
if (r)
local_cert_report_id = r->id();
}
transport = session_->GetTransport(transport_iter.second.content_name);
rtc::scoped_ptr<rtc::SSLCertificate> cert;
if (transport && transport->GetRemoteCertificate(cert.accept())) {
StatsReport* r = AddCertificateReports(cert.get());
if (r)
remote_cert_report_id = r->id();
}
for (const auto& channel_iter : transport_iter.second.channel_stats) {
StatsReport::Id id(StatsReport::NewComponentId(
transport_iter.second.content_name, channel_iter.component));
StatsReport* channel_report = reports_.ReplaceOrAddNew(id);
channel_report->set_timestamp(stats_gathering_started_);
channel_report->AddInt(StatsReport::kStatsValueNameComponent,
channel_iter.component);
if (local_cert_report_id.get()) {
channel_report->AddId(StatsReport::kStatsValueNameLocalCertificateId,
local_cert_report_id);
}
if (remote_cert_report_id.get()) {
channel_report->AddId(StatsReport::kStatsValueNameRemoteCertificateId,
remote_cert_report_id);
}
const std::string& srtp_cipher = channel_iter.srtp_cipher;
if (!srtp_cipher.empty()) {
channel_report->AddString(StatsReport::kStatsValueNameSrtpCipher,
srtp_cipher);
}
const std::string& ssl_cipher = channel_iter.ssl_cipher;
if (!ssl_cipher.empty()) {
channel_report->AddString(StatsReport::kStatsValueNameDtlsCipher,
ssl_cipher);
}
transport = session_->GetTransport(transport_iter.second.content_name);
rtc::scoped_ptr<rtc::SSLCertificate> cert;
if (transport && transport->GetRemoteCertificate(cert.accept())) {
StatsReport* r = AddCertificateReports(cert.get());
if (r)
remote_cert_report_id = r->id();
}
for (const auto& channel_iter : transport_iter.second.channel_stats) {
StatsReport::Id id(StatsReport::NewComponentId(
transport_iter.second.content_name, channel_iter.component));
StatsReport* channel_report = reports_.ReplaceOrAddNew(id);
channel_report->set_timestamp(stats_gathering_started_);
channel_report->AddInt(StatsReport::kStatsValueNameComponent,
channel_iter.component);
if (local_cert_report_id.get()) {
channel_report->AddId(StatsReport::kStatsValueNameLocalCertificateId,
local_cert_report_id);
}
if (remote_cert_report_id.get()) {
channel_report->AddId(StatsReport::kStatsValueNameRemoteCertificateId,
remote_cert_report_id);
}
const std::string& srtp_cipher = channel_iter.srtp_cipher;
if (!srtp_cipher.empty()) {
channel_report->AddString(StatsReport::kStatsValueNameSrtpCipher,
srtp_cipher);
}
const std::string& ssl_cipher = channel_iter.ssl_cipher;
if (!ssl_cipher.empty()) {
channel_report->AddString(StatsReport::kStatsValueNameDtlsCipher,
ssl_cipher);
}
int connection_id = 0;
for (const cricket::ConnectionInfo& info :
channel_iter.connection_infos) {
StatsReport* connection_report = AddConnectionInfoReport(
transport_iter.first, channel_iter.component, connection_id++,
channel_report->id(), info);
if (info.best_connection) {
channel_report->AddId(
StatsReport::kStatsValueNameSelectedCandidatePairId,
connection_report->id());
}
int connection_id = 0;
for (const cricket::ConnectionInfo& info :
channel_iter.connection_infos) {
StatsReport* connection_report = AddConnectionInfoReport(
transport_iter.first, channel_iter.component, connection_id++,
channel_report->id(), info);
if (info.best_connection) {
channel_report->AddId(
StatsReport::kStatsValueNameSelectedCandidatePairId,
connection_report->id());
}
}
}

View File

@ -88,7 +88,7 @@ class MockWebRtcSession : public webrtc::WebRtcSession {
// track.
MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32, std::string*));
MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32, std::string*));
MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
MOCK_METHOD1(GetTransportStats, bool(cricket::SessionStats*));
MOCK_METHOD1(GetTransport, cricket::Transport*(const std::string&));
};
@ -478,7 +478,7 @@ class StatsCollectorTest : public testing::Test {
signaling_(channel_manager_.get()),
session_(channel_manager_.get()) {
// By default, we ignore session GetStats calls.
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Return(false));
EXPECT_CALL(session_, GetTransportStats(_)).WillRepeatedly(Return(false));
EXPECT_CALL(session_, mediastream_signaling()).WillRepeatedly(
Return(&signaling_));
}
@ -565,7 +565,7 @@ class StatsCollectorTest : public testing::Test {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(vc_name);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
@ -666,7 +666,7 @@ class StatsCollectorTest : public testing::Test {
// Configure MockWebRtcSession
EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
.WillRepeatedly(Return(transport.get()));
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
Return(true)));
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
@ -782,7 +782,7 @@ TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
EXPECT_CALL(session_, GetTransport(_))
@ -825,7 +825,7 @@ TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
EXPECT_CALL(session_, GetTransport(_))
@ -936,7 +936,7 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
EXPECT_CALL(session_, GetTransport(_))
@ -1026,7 +1026,7 @@ TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
Return(true)));
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
@ -1096,7 +1096,7 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
@ -1134,7 +1134,7 @@ TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
const char kVideoChannelName[] = "video";
InitSessionStats(kVideoChannelName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
EXPECT_CALL(session_, GetTransport(_))
@ -1333,7 +1333,7 @@ TEST_F(StatsCollectorTest, NoTransport) {
// Configure MockWebRtcSession
EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
.WillRepeatedly(ReturnNull());
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
Return(true)));
@ -1399,7 +1399,7 @@ TEST_F(StatsCollectorTest, NoCertificates) {
// Configure MockWebRtcSession
EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
.WillRepeatedly(Return(transport.get()));
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
Return(true)));
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
@ -1519,7 +1519,7 @@ TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));
@ -1589,7 +1589,7 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
// Instruct the session to return stats containing the transport channel.
InitSessionStats(kVcName);
EXPECT_CALL(session_, GetStats(_))
EXPECT_CALL(session_, GetTransportStats(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
Return(true)));

View File

@ -910,6 +910,37 @@ WebRtcSession::Action WebRtcSession::GetAction(const std::string& type) {
return WebRtcSession::kOffer;
}
bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) {
ASSERT(signaling_thread()->IsCurrent());
const auto get_transport_stats = [stats](const std::string& content_name,
cricket::Transport* transport) {
const std::string& transport_id = transport->content_name();
stats->proxy_to_transport[content_name] = transport_id;
if (stats->transport_stats.find(transport_id)
!= stats->transport_stats.end()) {
// Transport stats already done for this transport.
return true;
}
cricket::TransportStats tstats;
if (!transport->GetStats(&tstats)) {
return false;
}
stats->transport_stats[transport_id] = tstats;
return true;
};
for (const auto& kv : transport_proxies()) {
cricket::Transport* transport = kv.second->impl();
if (transport && !get_transport_stats(kv.first, transport)) {
return false;
}
}
return true;
}
bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
if (state() == STATE_INIT) {
LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "

View File

@ -214,6 +214,10 @@ class WebRtcSession : public cricket::BaseSession,
void RemoveSctpDataStream(int sid) override;
bool ReadyToSendData() const override;
// Returns stats for all channels of all transports.
// This avoids exposing the internal structures used to track them.
virtual bool GetTransportStats(cricket::SessionStats* stats);
// Implements DataChannelFactory.
rtc::scoped_refptr<DataChannel> CreateDataChannel(
const std::string& label,

View File

@ -585,27 +585,6 @@ cricket::Transport* BaseSession::CreateTransport(
port_allocator(), identity_);
}
bool BaseSession::GetStats(SessionStats* stats) {
for (TransportMap::iterator iter = transports_.begin();
iter != transports_.end(); ++iter) {
std::string proxy_id = iter->second->content_name();
// We are ignoring not-yet-instantiated transports.
if (iter->second->impl()) {
std::string transport_id = iter->second->impl()->content_name();
stats->proxy_to_transport[proxy_id] = transport_id;
if (stats->transport_stats.find(transport_id)
== stats->transport_stats.end()) {
TransportStats subinfos;
if (!iter->second->impl()->GetStats(&subinfos)) {
return false;
}
stats->transport_stats[transport_id] = subinfos;
}
}
}
return true;
}
void BaseSession::SetState(State state) {
ASSERT(signaling_thread_->IsCurrent());
if (state != state_) {

View File

@ -166,6 +166,8 @@ typedef std::map<std::string, TransportProxy*> TransportMap;
typedef std::map<std::string, TransportStats> TransportStatsMap;
typedef std::map<std::string, std::string> ProxyTransportMap;
// TODO(pthatcher): Think of a better name for this. We already have
// a TransportStats in transport.h. Perhaps TransportsStats?
struct SessionStats {
ProxyTransportMap proxy_to_transport;
TransportStatsMap transport_stats;
@ -318,10 +320,6 @@ class BaseSession : public sigslot::has_slots<>,
virtual void DestroyChannel(const std::string& content_name,
int component);
// Returns stats for all channels of all transports.
// This avoids exposing the internal structures used to track them.
virtual bool GetStats(SessionStats* stats);
rtc::SSLIdentity* identity() { return identity_; }
protected: