RTCStatsCollector: Utilize network thread to minimize thread hops.
(This is a re-upload of https://codereview.webrtc.org/2567243003/, the CQ stopped working there.) The previously used WebRtcSession::GetTransportStats did a synchronous invoke per channel (voice, video, data) on the signaling thread to the network thread - e.g. 3 blocking invokes. It is replaced by WebRtcSession::GetStats[_s] which can be invoked on the signaling thread or on any thread if a ChannelNamePairs argument is present (provided by WebRtcSession::GetChannelNamePairs on the signaling thread). With these changes, and changes allowing the getting of certificates from any thread, the RTCStatsCollector can turn the 3 blocking thread invokes into 1 non-blocking invoke. BUG=webrtc:6875, chromium:627816 Review-Url: https://codereview.webrtc.org/2583883002 Cr-Commit-Position: refs/heads/master@{#15672}
This commit is contained in:
parent
20d05a9f71
commit
df6075a77f
@ -416,9 +416,32 @@ void RTCStatsCollector::GetStatsReport(
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_,
|
||||
rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnSignalingThread,
|
||||
rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
|
||||
|
||||
// TODO(hbos): No stats are gathered by
|
||||
// |ProducePartialResultsOnWorkerThread|, remove it.
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
|
||||
rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnWorkerThread,
|
||||
rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
|
||||
|
||||
// Prepare |channel_names_| and |media_info_| for use in
|
||||
// |ProducePartialResultsOnNetworkThread|.
|
||||
channel_name_pairs_.reset(new ChannelNamePairs());
|
||||
if (pc_->session()->voice_channel()) {
|
||||
channel_name_pairs_->voice = rtc::Optional<ChannelNamePair>(
|
||||
ChannelNamePair(pc_->session()->voice_channel()->content_name(),
|
||||
pc_->session()->voice_channel()->transport_name()));
|
||||
}
|
||||
if (pc_->session()->video_channel()) {
|
||||
channel_name_pairs_->video = rtc::Optional<ChannelNamePair>(
|
||||
ChannelNamePair(pc_->session()->video_channel()->content_name(),
|
||||
pc_->session()->video_channel()->transport_name()));
|
||||
}
|
||||
if (pc_->session()->data_channel()) {
|
||||
channel_name_pairs_->data = rtc::Optional<ChannelNamePair>(
|
||||
ChannelNamePair(pc_->session()->data_channel()->content_name(),
|
||||
pc_->session()->data_channel()->transport_name()));
|
||||
}
|
||||
media_info_.reset(PrepareMediaInfo_s().release());
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, network_thread_,
|
||||
rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnNetworkThread,
|
||||
rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
|
||||
@ -436,23 +459,6 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThread(
|
||||
rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
|
||||
timestamp_us);
|
||||
|
||||
SessionStats session_stats;
|
||||
if (pc_->session()->GetTransportStats(&session_stats)) {
|
||||
std::map<std::string, CertificateStatsPair> transport_cert_stats =
|
||||
PrepareTransportCertificateStats(session_stats);
|
||||
MediaInfo media_info = PrepareMediaInfo(session_stats);
|
||||
|
||||
ProduceCertificateStats_s(
|
||||
timestamp_us, transport_cert_stats, report.get());
|
||||
ProduceCodecStats_s(
|
||||
timestamp_us, media_info, report.get());
|
||||
ProduceIceCandidateAndPairStats_s(
|
||||
timestamp_us, session_stats, report.get());
|
||||
ProduceRTPStreamStats_s(
|
||||
timestamp_us, session_stats, media_info, report.get());
|
||||
ProduceTransportStats_s(
|
||||
timestamp_us, session_stats, transport_cert_stats, report.get());
|
||||
}
|
||||
ProduceDataChannelStats_s(timestamp_us, report.get());
|
||||
ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get());
|
||||
ProducePeerConnectionStats_s(timestamp_us, report.get());
|
||||
@ -466,13 +472,8 @@ void RTCStatsCollector::ProducePartialResultsOnWorkerThread(
|
||||
rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
|
||||
timestamp_us);
|
||||
|
||||
// TODO(hbos): Gather stats on worker thread.
|
||||
// pc_->session()'s channels are owned by the signaling thread but there are
|
||||
// some stats that are gathered on the worker thread. Instead of a synchronous
|
||||
// invoke on "s->w" we could to the "w" work here asynchronously if it wasn't
|
||||
// for the ownership issue. Synchronous invokes in other places makes it
|
||||
// difficult to introduce locks without introducing deadlocks and the channels
|
||||
// are not reference counted.
|
||||
// TODO(hbos): There are no stats to be gathered on this thread, remove this
|
||||
// method.
|
||||
|
||||
AddPartialResults(report);
|
||||
}
|
||||
@ -483,13 +484,23 @@ void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
|
||||
rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
|
||||
timestamp_us);
|
||||
|
||||
// TODO(hbos): Gather stats on network thread.
|
||||
// pc_->session()'s channels are owned by the signaling thread but there are
|
||||
// some stats that are gathered on the network thread. Instead of a
|
||||
// synchronous invoke on "s->n" we could to the "n" work here asynchronously
|
||||
// if it wasn't for the ownership issue. Synchronous invokes in other places
|
||||
// makes it difficult to introduce locks without introducing deadlocks and the
|
||||
// channels are not reference counted.
|
||||
std::unique_ptr<SessionStats> session_stats =
|
||||
pc_->session()->GetStats(*channel_name_pairs_);
|
||||
if (session_stats) {
|
||||
std::map<std::string, CertificateStatsPair> transport_cert_stats =
|
||||
PrepareTransportCertificateStats_n(*session_stats);
|
||||
|
||||
ProduceCertificateStats_n(
|
||||
timestamp_us, transport_cert_stats, report.get());
|
||||
ProduceCodecStats_n(
|
||||
timestamp_us, *media_info_, report.get());
|
||||
ProduceIceCandidateAndPairStats_n(
|
||||
timestamp_us, *session_stats, report.get());
|
||||
ProduceRTPStreamStats_n(
|
||||
timestamp_us, *session_stats, *media_info_, report.get());
|
||||
ProduceTransportStats_n(
|
||||
timestamp_us, *session_stats, transport_cert_stats, report.get());
|
||||
}
|
||||
|
||||
AddPartialResults(report);
|
||||
}
|
||||
@ -534,11 +545,11 @@ void RTCStatsCollector::DeliverCachedReport() {
|
||||
callbacks_.clear();
|
||||
}
|
||||
|
||||
void RTCStatsCollector::ProduceCertificateStats_s(
|
||||
void RTCStatsCollector::ProduceCertificateStats_n(
|
||||
int64_t timestamp_us,
|
||||
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
||||
RTCStatsReport* report) const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
for (const auto& transport_cert_stats_pair : transport_cert_stats) {
|
||||
if (transport_cert_stats_pair.second.local) {
|
||||
ProduceCertificateStatsFromSSLCertificateStats(
|
||||
@ -551,10 +562,10 @@ void RTCStatsCollector::ProduceCertificateStats_s(
|
||||
}
|
||||
}
|
||||
|
||||
void RTCStatsCollector::ProduceCodecStats_s(
|
||||
void RTCStatsCollector::ProduceCodecStats_n(
|
||||
int64_t timestamp_us, const MediaInfo& media_info,
|
||||
RTCStatsReport* report) const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
// Audio
|
||||
if (media_info.voice) {
|
||||
// Inbound
|
||||
@ -605,10 +616,10 @@ void RTCStatsCollector::ProduceDataChannelStats_s(
|
||||
}
|
||||
}
|
||||
|
||||
void RTCStatsCollector::ProduceIceCandidateAndPairStats_s(
|
||||
void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
RTCStatsReport* report) const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
for (const auto& transport_stats : session_stats.transport_stats) {
|
||||
for (const auto& channel_stats : transport_stats.second.channel_stats) {
|
||||
std::string transport_id = RTCTransportStatsIDFromTransportChannel(
|
||||
@ -681,10 +692,10 @@ void RTCStatsCollector::ProducePeerConnectionStats_s(
|
||||
report->AddStats(std::move(stats));
|
||||
}
|
||||
|
||||
void RTCStatsCollector::ProduceRTPStreamStats_s(
|
||||
void RTCStatsCollector::ProduceRTPStreamStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
const MediaInfo& media_info, RTCStatsReport* report) const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
|
||||
// Audio
|
||||
if (media_info.voice) {
|
||||
@ -788,11 +799,11 @@ void RTCStatsCollector::ProduceRTPStreamStats_s(
|
||||
}
|
||||
}
|
||||
|
||||
void RTCStatsCollector::ProduceTransportStats_s(
|
||||
void RTCStatsCollector::ProduceTransportStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
||||
RTCStatsReport* report) const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
for (const auto& transport : session_stats.transport_stats) {
|
||||
// Get reference to RTCP channel, if it exists.
|
||||
std::string rtcp_transport_stats_id;
|
||||
@ -855,9 +866,9 @@ void RTCStatsCollector::ProduceTransportStats_s(
|
||||
}
|
||||
|
||||
std::map<std::string, RTCStatsCollector::CertificateStatsPair>
|
||||
RTCStatsCollector::PrepareTransportCertificateStats(
|
||||
RTCStatsCollector::PrepareTransportCertificateStats_n(
|
||||
const SessionStats& session_stats) const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
std::map<std::string, CertificateStatsPair> transport_cert_stats;
|
||||
for (const auto& transport_stats : session_stats.transport_stats) {
|
||||
CertificateStatsPair certificate_stats_pair;
|
||||
@ -880,20 +891,21 @@ RTCStatsCollector::PrepareTransportCertificateStats(
|
||||
return transport_cert_stats;
|
||||
}
|
||||
|
||||
RTCStatsCollector::MediaInfo RTCStatsCollector::PrepareMediaInfo(
|
||||
const SessionStats& session_stats) const {
|
||||
MediaInfo media_info;
|
||||
std::unique_ptr<RTCStatsCollector::MediaInfo>
|
||||
RTCStatsCollector::PrepareMediaInfo_s() const {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
std::unique_ptr<MediaInfo> media_info(new MediaInfo());
|
||||
if (pc_->session()->voice_channel()) {
|
||||
cricket::VoiceMediaInfo voice_media_info;
|
||||
if (pc_->session()->voice_channel()->GetStats(&voice_media_info)) {
|
||||
media_info.voice = rtc::Optional<cricket::VoiceMediaInfo>(
|
||||
media_info->voice = rtc::Optional<cricket::VoiceMediaInfo>(
|
||||
std::move(voice_media_info));
|
||||
}
|
||||
}
|
||||
if (pc_->session()->video_channel()) {
|
||||
cricket::VideoMediaInfo video_media_info;
|
||||
if (pc_->session()->video_channel()->GetStats(&video_media_info)) {
|
||||
media_info.video = rtc::Optional<cricket::VideoMediaInfo>(
|
||||
media_info->video = rtc::Optional<cricket::VideoMediaInfo>(
|
||||
std::move(video_media_info));
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ namespace webrtc {
|
||||
|
||||
class PeerConnection;
|
||||
struct SessionStats;
|
||||
struct ChannelNamePairs;
|
||||
|
||||
class RTCStatsCollectorCallback : public virtual rtc::RefCountInterface {
|
||||
public:
|
||||
@ -97,19 +98,19 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
|
||||
void DeliverCachedReport();
|
||||
|
||||
// Produces |RTCCertificateStats|.
|
||||
void ProduceCertificateStats_s(
|
||||
void ProduceCertificateStats_n(
|
||||
int64_t timestamp_us,
|
||||
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
||||
RTCStatsReport* report) const;
|
||||
// Produces |RTCCodecStats|.
|
||||
void ProduceCodecStats_s(
|
||||
void ProduceCodecStats_n(
|
||||
int64_t timestamp_us, const MediaInfo& media_info,
|
||||
RTCStatsReport* report) const;
|
||||
// Produces |RTCDataChannelStats|.
|
||||
void ProduceDataChannelStats_s(
|
||||
int64_t timestamp_us, RTCStatsReport* report) const;
|
||||
// Produces |RTCIceCandidatePairStats| and |RTCIceCandidateStats|.
|
||||
void ProduceIceCandidateAndPairStats_s(
|
||||
void ProduceIceCandidateAndPairStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
RTCStatsReport* report) const;
|
||||
// Produces |RTCMediaStreamStats| and |RTCMediaStreamTrackStats|.
|
||||
@ -119,19 +120,19 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
|
||||
void ProducePeerConnectionStats_s(
|
||||
int64_t timestamp_us, RTCStatsReport* report) const;
|
||||
// Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|.
|
||||
void ProduceRTPStreamStats_s(
|
||||
void ProduceRTPStreamStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
const MediaInfo& media_info, RTCStatsReport* report) const;
|
||||
// Produces |RTCTransportStats|.
|
||||
void ProduceTransportStats_s(
|
||||
void ProduceTransportStats_n(
|
||||
int64_t timestamp_us, const SessionStats& session_stats,
|
||||
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
||||
RTCStatsReport* report) const;
|
||||
|
||||
// Helper function to stats-producing functions.
|
||||
std::map<std::string, CertificateStatsPair>
|
||||
PrepareTransportCertificateStats(const SessionStats& session_stats) const;
|
||||
MediaInfo PrepareMediaInfo(const SessionStats& session_stats) const;
|
||||
PrepareTransportCertificateStats_n(const SessionStats& session_stats) const;
|
||||
std::unique_ptr<MediaInfo> PrepareMediaInfo_s() const;
|
||||
|
||||
// Slots for signals (sigslot) that are wired up to |pc_|.
|
||||
void OnDataChannelCreated(DataChannel* channel);
|
||||
@ -150,6 +151,13 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
|
||||
rtc::scoped_refptr<RTCStatsReport> partial_report_;
|
||||
std::vector<rtc::scoped_refptr<RTCStatsCollectorCallback>> callbacks_;
|
||||
|
||||
// Set in |GetStatsReport|, used in |ProducePartialResultsOnNetworkThread|
|
||||
// (not passed as arguments to avoid copies). This is thread safe - it is set
|
||||
// at the start of |GetStatsReport| after making sure there are no pending
|
||||
// stats requests in progress.
|
||||
std::unique_ptr<ChannelNamePairs> channel_name_pairs_;
|
||||
std::unique_ptr<MediaInfo> media_info_;
|
||||
|
||||
// A timestamp, in microseconds, that is based on a timer that is
|
||||
// monotonically increasing. That is, even if the system clock is modified the
|
||||
// difference between the timer and this timestamp is how fresh the cached
|
||||
|
||||
@ -313,7 +313,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_, GetTransportStats(_)).WillRepeatedly(Return(false));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
|
||||
EXPECT_CALL(session_, GetLocalCertificate(_, _)).WillRepeatedly(
|
||||
Return(false));
|
||||
EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
|
||||
@ -628,10 +628,11 @@ 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(), GetTransportStats(_)).WillRepeatedly(Invoke(
|
||||
[this](SessionStats* stats) {
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
std::unique_ptr<SessionStats> stats(new SessionStats());
|
||||
stats->transport_stats["transport"].transport_name = "transport";
|
||||
return true;
|
||||
return stats;
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
|
||||
Invoke([this, &local_certinfo](const std::string& transport_name,
|
||||
@ -713,8 +714,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) {
|
||||
session_stats.transport_stats["TransportName"].transport_name =
|
||||
"TransportName";
|
||||
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats), Return(true)));
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), voice_channel())
|
||||
.WillRepeatedly(Return(&voice_channel));
|
||||
EXPECT_CALL(test_->session(), video_channel())
|
||||
@ -791,11 +794,12 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
|
||||
video_remote_certinfo->ders);
|
||||
|
||||
// Mock the session to return the local and remote certificates.
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
|
||||
[this](SessionStats* stats) {
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
std::unique_ptr<SessionStats> stats(new SessionStats());
|
||||
stats->transport_stats["audio"].transport_name = "audio";
|
||||
stats->transport_stats["video"].transport_name = "video";
|
||||
return true;
|
||||
return stats;
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
|
||||
Invoke([this, &audio_local_certinfo, &video_local_certinfo](
|
||||
@ -850,10 +854,11 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
|
||||
CreateFakeCertificateAndInfoFromDers(remote_ders);
|
||||
|
||||
// Mock the session to return the local and remote certificates.
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
|
||||
[this](SessionStats* stats) {
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
std::unique_ptr<SessionStats> stats(new SessionStats());
|
||||
stats->transport_stats["transport"].transport_name = "transport";
|
||||
return true;
|
||||
return stats;
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
|
||||
Invoke([this, &local_certinfo](const std::string& transport_name,
|
||||
@ -978,10 +983,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
|
||||
b_transport_channel_stats);
|
||||
|
||||
// Mock the session to return the desired candidates.
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
|
||||
[this, &session_stats](SessionStats* stats) {
|
||||
*stats = session_stats;
|
||||
return true;
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
|
||||
rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
|
||||
@ -1022,10 +1026,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
||||
transport_channel_stats);
|
||||
|
||||
// Mock the session to return the desired candidates.
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
|
||||
[this, &session_stats](SessionStats* stats) {
|
||||
*stats = session_stats;
|
||||
return true;
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
|
||||
rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
|
||||
@ -1387,8 +1390,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
|
||||
session_stats.transport_stats["TransportName"].channel_stats.push_back(
|
||||
channel_stats);
|
||||
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats), Return(true)));
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), voice_channel())
|
||||
.WillRepeatedly(Return(&voice_channel));
|
||||
|
||||
@ -1459,8 +1464,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
||||
session_stats.transport_stats["TransportName"].channel_stats.push_back(
|
||||
channel_stats);
|
||||
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats), Return(true)));
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), video_channel())
|
||||
.WillRepeatedly(Return(&video_channel));
|
||||
|
||||
@ -1529,8 +1536,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
|
||||
session_stats.transport_stats["TransportName"].channel_stats.push_back(
|
||||
channel_stats);
|
||||
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats), Return(true)));
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), voice_channel())
|
||||
.WillRepeatedly(Return(&voice_channel));
|
||||
|
||||
@ -1597,8 +1606,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
|
||||
session_stats.transport_stats["TransportName"].channel_stats.push_back(
|
||||
channel_stats);
|
||||
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats), Return(true)));
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), video_channel())
|
||||
.WillRepeatedly(Return(&video_channel));
|
||||
|
||||
@ -1677,8 +1688,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Default) {
|
||||
session_stats.transport_stats["TransportName"].channel_stats.push_back(
|
||||
channel_stats);
|
||||
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats), Return(true)));
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
EXPECT_CALL(test_->session(), voice_channel())
|
||||
.WillRepeatedly(Return(&voice_channel));
|
||||
EXPECT_CALL(test_->session(), video_channel())
|
||||
@ -1754,10 +1767,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
||||
|
||||
|
||||
// Mock the session to return the desired candidates.
|
||||
EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
|
||||
[this, &session_stats](SessionStats* stats) {
|
||||
*stats = session_stats;
|
||||
return true;
|
||||
EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
|
||||
}));
|
||||
|
||||
// Get stats without RTCP, an active connection or certificates.
|
||||
|
||||
@ -675,8 +675,8 @@ void StatsCollector::ExtractSessionInfo() {
|
||||
report->AddBoolean(StatsReport::kStatsValueNameInitiator,
|
||||
pc_->session()->initial_offerer());
|
||||
|
||||
SessionStats stats;
|
||||
if (!pc_->session()->GetTransportStats(&stats)) {
|
||||
std::unique_ptr<SessionStats> stats = pc_->session()->GetStats_s();
|
||||
if (!stats) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -686,9 +686,9 @@ void StatsCollector::ExtractSessionInfo() {
|
||||
// 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;
|
||||
proxy_to_transport_ = stats->proxy_to_transport;
|
||||
|
||||
for (const auto& transport_iter : stats.transport_stats) {
|
||||
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.
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
using testing::_;
|
||||
using testing::DoAll;
|
||||
using testing::Field;
|
||||
using testing::Invoke;
|
||||
using testing::Return;
|
||||
using testing::ReturnNull;
|
||||
using testing::ReturnRef;
|
||||
@ -509,7 +510,7 @@ class StatsCollectorTest : public testing::Test {
|
||||
&event_log_)),
|
||||
session_(media_controller_.get()) {
|
||||
// By default, we ignore session GetStats calls.
|
||||
EXPECT_CALL(session_, GetTransportStats(_)).WillRepeatedly(Return(false));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
|
||||
// Add default returns for mock classes.
|
||||
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||
@ -612,9 +613,11 @@ class StatsCollectorTest : public testing::Test {
|
||||
|
||||
// Instruct the session to return stats containing the transport channel.
|
||||
InitSessionStats(vc_name);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
// Constructs an ssrc stats update.
|
||||
if (voice_sender_info)
|
||||
@ -712,9 +715,11 @@ class StatsCollectorTest : public testing::Test {
|
||||
EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(
|
||||
transport_stats.transport_name))
|
||||
.WillOnce(Return(remote_cert.release()));
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillOnce(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats));
|
||||
}));
|
||||
|
||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||
|
||||
@ -853,9 +858,11 @@ TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
|
||||
const char kVideoChannelName[] = "video";
|
||||
|
||||
InitSessionStats(kVideoChannelName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
|
||||
cricket::VideoChannel video_channel(
|
||||
@ -900,9 +907,11 @@ TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
|
||||
const char kVideoChannelName[] = "video";
|
||||
|
||||
InitSessionStats(kVideoChannelName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
|
||||
cricket::VideoChannel video_channel(
|
||||
@ -1013,9 +1022,11 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
|
||||
|
||||
const char kVideoChannelName[] = "video";
|
||||
InitSessionStats(kVideoChannelName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
|
||||
cricket::VideoChannel video_channel(
|
||||
@ -1110,9 +1121,11 @@ TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
|
||||
Return(true)));
|
||||
|
||||
InitSessionStats(kVcName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||
StatsReports reports;
|
||||
@ -1181,9 +1194,11 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
|
||||
|
||||
// Instruct the session to return stats containing the transport channel.
|
||||
InitSessionStats(kVcName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
// Constructs an ssrc stats update.
|
||||
cricket::VideoMediaInfo stats_read;
|
||||
@ -1224,9 +1239,11 @@ TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
|
||||
|
||||
const char kVideoChannelName[] = "video";
|
||||
InitSessionStats(kVideoChannelName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
|
||||
cricket::VideoChannel video_channel(
|
||||
@ -1430,9 +1447,11 @@ TEST_F(StatsCollectorTest, NoTransport) {
|
||||
transport_stats;
|
||||
|
||||
// Configure MockWebRtcSession
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats));
|
||||
}));
|
||||
|
||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||
stats.GetStats(NULL, &reports);
|
||||
@ -1487,9 +1506,11 @@ TEST_F(StatsCollectorTest, NoCertificates) {
|
||||
transport_stats;
|
||||
|
||||
// Configure MockWebRtcSession
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[&session_stats](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats));
|
||||
}));
|
||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||
stats.GetStats(NULL, &reports);
|
||||
|
||||
@ -1566,8 +1587,11 @@ TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) {
|
||||
|
||||
// Instruct the session to return stats containing the transport channel.
|
||||
InitSessionStats(kVcName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_), Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
cricket::VoiceSenderInfo voice_sender_info;
|
||||
voice_sender_info.add_ssrc(kSsrcOfTrack);
|
||||
@ -1720,9 +1744,11 @@ TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
|
||||
|
||||
// Instruct the session to return stats containing the transport channel.
|
||||
InitSessionStats(kVcName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
|
||||
cricket::VoiceSenderInfo voice_sender_info;
|
||||
@ -1794,9 +1820,11 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
|
||||
|
||||
// Instruct the session to return stats containing the transport channel.
|
||||
InitSessionStats(kVcName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||
Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
cricket::VoiceSenderInfo voice_sender_info;
|
||||
InitVoiceSenderInfo(&voice_sender_info);
|
||||
@ -1914,8 +1942,11 @@ TEST_F(StatsCollectorTest, VerifyVideoSendSsrcStats) {
|
||||
const char kVideoChannelName[] = "video";
|
||||
|
||||
InitSessionStats(kVideoChannelName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_), Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
|
||||
cricket::VideoChannel video_channel(
|
||||
@ -1959,8 +1990,11 @@ TEST_F(StatsCollectorTest, VerifyVideoReceiveSsrcStats) {
|
||||
const char kVideoChannelName[] = "video";
|
||||
|
||||
InitSessionStats(kVideoChannelName);
|
||||
EXPECT_CALL(session_, GetTransportStats(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_), Return(true)));
|
||||
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
|
||||
[this](const ChannelNamePairs&) {
|
||||
return std::unique_ptr<SessionStats>(
|
||||
new SessionStats(session_stats_));
|
||||
}));
|
||||
|
||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
|
||||
cricket::VideoChannel video_channel(
|
||||
|
||||
@ -42,7 +42,8 @@ class MockWebRtcSession : public webrtc::WebRtcSession {
|
||||
// track.
|
||||
MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32_t, std::string*));
|
||||
MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32_t, std::string*));
|
||||
MOCK_METHOD1(GetTransportStats, bool(SessionStats*));
|
||||
MOCK_METHOD1(GetStats,
|
||||
std::unique_ptr<SessionStats>(const ChannelNamePairs&));
|
||||
MOCK_METHOD2(GetLocalCertificate,
|
||||
bool(const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate));
|
||||
|
||||
@ -970,50 +970,43 @@ bool WebRtcSession::GetTransportDescription(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebRtcSession::GetTransportStats(SessionStats* stats) {
|
||||
std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() {
|
||||
ASSERT(signaling_thread()->IsCurrent());
|
||||
return (GetChannelTransportStats(voice_channel(), stats) &&
|
||||
GetChannelTransportStats(video_channel(), stats) &&
|
||||
GetChannelTransportStats(data_channel(), stats));
|
||||
ChannelNamePairs channel_name_pairs;
|
||||
if (voice_channel()) {
|
||||
channel_name_pairs.voice = rtc::Optional<ChannelNamePair>(ChannelNamePair(
|
||||
voice_channel()->content_name(), voice_channel()->transport_name()));
|
||||
}
|
||||
if (video_channel()) {
|
||||
channel_name_pairs.video = rtc::Optional<ChannelNamePair>(ChannelNamePair(
|
||||
video_channel()->content_name(), video_channel()->transport_name()));
|
||||
}
|
||||
if (data_channel()) {
|
||||
channel_name_pairs.data = rtc::Optional<ChannelNamePair>(ChannelNamePair(
|
||||
data_channel()->content_name(), data_channel()->transport_name()));
|
||||
}
|
||||
return GetStats(channel_name_pairs);
|
||||
}
|
||||
|
||||
bool WebRtcSession::GetChannelTransportStats(cricket::BaseChannel* ch,
|
||||
SessionStats* stats) {
|
||||
ASSERT(signaling_thread()->IsCurrent());
|
||||
if (!ch) {
|
||||
// Not using this channel.
|
||||
return true;
|
||||
std::unique_ptr<SessionStats> WebRtcSession::GetStats(
|
||||
const ChannelNamePairs& channel_name_pairs) {
|
||||
if (network_thread()->IsCurrent()) {
|
||||
return GetStats_n(channel_name_pairs);
|
||||
}
|
||||
|
||||
const std::string& content_name = ch->content_name();
|
||||
const std::string& transport_name = ch->transport_name();
|
||||
stats->proxy_to_transport[content_name] = transport_name;
|
||||
if (stats->transport_stats.find(transport_name) !=
|
||||
stats->transport_stats.end()) {
|
||||
// Transport stats already done for this transport.
|
||||
return true;
|
||||
}
|
||||
|
||||
cricket::TransportStats tstats;
|
||||
if (!transport_controller_->GetStats(transport_name, &tstats)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stats->transport_stats[transport_name] = tstats;
|
||||
return true;
|
||||
return network_thread()->Invoke<std::unique_ptr<SessionStats>>(
|
||||
RTC_FROM_HERE,
|
||||
rtc::Bind(&WebRtcSession::GetStats_n, this, channel_name_pairs));
|
||||
}
|
||||
|
||||
bool WebRtcSession::GetLocalCertificate(
|
||||
const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
|
||||
ASSERT(signaling_thread()->IsCurrent());
|
||||
return transport_controller_->GetLocalCertificate(transport_name,
|
||||
certificate);
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::SSLCertificate> WebRtcSession::GetRemoteSSLCertificate(
|
||||
const std::string& transport_name) {
|
||||
ASSERT(signaling_thread()->IsCurrent());
|
||||
return transport_controller_->GetRemoteSSLCertificate(transport_name);
|
||||
}
|
||||
|
||||
@ -1716,6 +1709,28 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<SessionStats> WebRtcSession::GetStats_n(
|
||||
const ChannelNamePairs& channel_name_pairs) {
|
||||
ASSERT(network_thread()->IsCurrent());
|
||||
std::unique_ptr<SessionStats> session_stats(new SessionStats());
|
||||
for (const auto channel_name_pair : { &channel_name_pairs.voice,
|
||||
&channel_name_pairs.video,
|
||||
&channel_name_pairs.data }) {
|
||||
if (*channel_name_pair) {
|
||||
cricket::TransportStats transport_stats;
|
||||
if (!transport_controller_->GetStats((*channel_name_pair)->transport_name,
|
||||
&transport_stats)) {
|
||||
return nullptr;
|
||||
}
|
||||
session_stats->proxy_to_transport[(*channel_name_pair)->content_name] =
|
||||
(*channel_name_pair)->transport_name;
|
||||
session_stats->transport_stats[(*channel_name_pair)->transport_name] =
|
||||
std::move(transport_stats);
|
||||
}
|
||||
}
|
||||
return session_stats;
|
||||
}
|
||||
|
||||
void WebRtcSession::OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp) {
|
||||
SetError(ERROR_TRANSPORT,
|
||||
rtcp ? kDtlsSetupFailureRtcp : kDtlsSetupFailureRtp);
|
||||
|
||||
@ -115,6 +115,20 @@ struct SessionStats {
|
||||
TransportStatsMap transport_stats;
|
||||
};
|
||||
|
||||
struct ChannelNamePair {
|
||||
ChannelNamePair(
|
||||
const std::string& content_name, const std::string& transport_name)
|
||||
: content_name(content_name), transport_name(transport_name) {}
|
||||
std::string content_name;
|
||||
std::string transport_name;
|
||||
};
|
||||
|
||||
struct ChannelNamePairs {
|
||||
rtc::Optional<ChannelNamePair> voice;
|
||||
rtc::Optional<ChannelNamePair> video;
|
||||
rtc::Optional<ChannelNamePair> data;
|
||||
};
|
||||
|
||||
// A WebRtcSession manages general session state. This includes negotiation
|
||||
// of both the application-level and network-level protocols: the former
|
||||
// defines what will be sent and the latter defines how it will be sent. Each
|
||||
@ -194,6 +208,7 @@ class WebRtcSession :
|
||||
virtual cricket::DataChannel* data_channel() {
|
||||
return data_channel_.get();
|
||||
}
|
||||
std::unique_ptr<ChannelNamePairs> GetChannelNamePairs();
|
||||
|
||||
cricket::BaseChannel* GetChannel(const std::string& content_name);
|
||||
|
||||
@ -261,10 +276,14 @@ class WebRtcSession :
|
||||
|
||||
// Returns stats for all channels of all transports.
|
||||
// This avoids exposing the internal structures used to track them.
|
||||
virtual bool GetTransportStats(SessionStats* stats);
|
||||
|
||||
// Get stats for a specific channel
|
||||
bool GetChannelTransportStats(cricket::BaseChannel* ch, SessionStats* stats);
|
||||
// The parameterless version creates |ChannelNamePairs| from |voice_channel|,
|
||||
// |video_channel| and |voice_channel| if available - this requires it to be
|
||||
// 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(
|
||||
const ChannelNamePairs& channel_name_pairs);
|
||||
|
||||
// virtual so it can be mocked in unit tests
|
||||
virtual bool GetLocalCertificate(
|
||||
@ -415,6 +434,9 @@ class WebRtcSession :
|
||||
bool CreateDataChannel(const cricket::ContentInfo* content,
|
||||
const std::string* bundle_transport);
|
||||
|
||||
std::unique_ptr<SessionStats> GetStats_n(
|
||||
const ChannelNamePairs& channel_name_pairs);
|
||||
|
||||
// Listens to SCTP CONTROL messages on unused SIDs and process them as OPEN
|
||||
// messages.
|
||||
void OnDataChannelMessageReceived(cricket::DataChannel* channel,
|
||||
@ -489,7 +511,7 @@ class WebRtcSession :
|
||||
const std::string sid_;
|
||||
bool initial_offerer_ = false;
|
||||
|
||||
std::unique_ptr<cricket::TransportController> transport_controller_;
|
||||
const std::unique_ptr<cricket::TransportController> transport_controller_;
|
||||
MediaControllerInterface* media_controller_;
|
||||
std::unique_ptr<cricket::VoiceChannel> voice_channel_;
|
||||
std::unique_ptr<cricket::VideoChannel> video_channel_;
|
||||
|
||||
@ -3039,9 +3039,8 @@ TEST_F(WebRtcSessionTest, TestIgnoreCandidatesForUnusedTransportWhenBundling) {
|
||||
// Checks if one of the transport channels contains a connection using a given
|
||||
// port.
|
||||
auto connection_with_remote_port = [this, voice_channel](int port) {
|
||||
SessionStats stats;
|
||||
session_->GetChannelTransportStats(voice_channel, &stats);
|
||||
for (auto& kv : stats.transport_stats) {
|
||||
std::unique_ptr<webrtc::SessionStats> stats = session_->GetStats_s();
|
||||
for (auto& kv : stats->transport_stats) {
|
||||
for (auto& chan_stat : kv.second.channel_stats) {
|
||||
for (auto& conn_info : chan_stat.connection_infos) {
|
||||
if (conn_info.remote_candidate.address().port() == port) {
|
||||
|
||||
@ -141,6 +141,9 @@ bool TransportController::SetLocalCertificate(
|
||||
bool TransportController::GetLocalCertificate(
|
||||
const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const {
|
||||
if (network_thread_->IsCurrent()) {
|
||||
return GetLocalCertificate_n(transport_name, certificate);
|
||||
}
|
||||
return network_thread_->Invoke<bool>(
|
||||
RTC_FROM_HERE, rtc::Bind(&TransportController::GetLocalCertificate_n,
|
||||
this, transport_name, certificate));
|
||||
@ -149,6 +152,9 @@ bool TransportController::GetLocalCertificate(
|
||||
std::unique_ptr<rtc::SSLCertificate>
|
||||
TransportController::GetRemoteSSLCertificate(
|
||||
const std::string& transport_name) const {
|
||||
if (network_thread_->IsCurrent()) {
|
||||
return GetRemoteSSLCertificate_n(transport_name);
|
||||
}
|
||||
return network_thread_->Invoke<std::unique_ptr<rtc::SSLCertificate>>(
|
||||
RTC_FROM_HERE, rtc::Bind(&TransportController::GetRemoteSSLCertificate_n,
|
||||
this, transport_name));
|
||||
@ -206,6 +212,9 @@ bool TransportController::ReadyForRemoteCandidates(
|
||||
|
||||
bool TransportController::GetStats(const std::string& transport_name,
|
||||
TransportStats* stats) {
|
||||
if (network_thread_->IsCurrent()) {
|
||||
return GetStats_n(transport_name, stats);
|
||||
}
|
||||
return network_thread_->Invoke<bool>(
|
||||
RTC_FROM_HERE,
|
||||
rtc::Bind(&TransportController::GetStats_n, this, transport_name, stats));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user