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:
parent
aba9219e5c
commit
c04a97f054
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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 "
|
||||
|
@ -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,
|
||||
|
@ -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_) {
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user