mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-20 09:07:52 +01:00
Add collection of usage signatures on PeerConnections
This generates a number that represent a set of bits that indicates how a PeerConnection has been used over time. Bug: chromium:718508 Change-Id: I6df177684c50bc825bc41ea97996574292084d41 Reviewed-on: https://webrtc-review.googlesource.com/79823 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> Commit-Queue: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23471}
This commit is contained in:
parent
879f5a34a5
commit
8ebba7420c
4 changed files with 96 additions and 2 deletions
|
@ -45,6 +45,7 @@ enum PeerConnectionEnumCounterType {
|
|||
// The next 2 counters log the value of srtp_err_status_t defined in libsrtp.
|
||||
kEnumCounterSrtpUnprotectError,
|
||||
kEnumCounterSrtcpUnprotectError,
|
||||
kEnumCounterUsagePattern,
|
||||
kPeerConnectionEnumCounterMax
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "pc/peerconnection.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
@ -1034,7 +1035,6 @@ bool PeerConnection::Initialize(
|
|||
RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1417,6 +1417,7 @@ PeerConnection::CreateSender(
|
|||
new AudioRtpSender(worker_thread(),
|
||||
static_cast<AudioTrackInterface*>(track.get()),
|
||||
stream_ids, stats_.get()));
|
||||
NoteUsageEvent(UsageEvent::AUDIO_ADDED);
|
||||
} else {
|
||||
RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
|
||||
RTC_DCHECK(!track ||
|
||||
|
@ -1426,6 +1427,7 @@ PeerConnection::CreateSender(
|
|||
new VideoRtpSender(worker_thread(),
|
||||
static_cast<VideoTrackInterface*>(track.get()),
|
||||
stream_ids));
|
||||
NoteUsageEvent(UsageEvent::VIDEO_ADDED);
|
||||
}
|
||||
sender->internal()->set_stream_ids(stream_ids);
|
||||
return sender;
|
||||
|
@ -1440,11 +1442,13 @@ PeerConnection::CreateReceiver(cricket::MediaType media_type,
|
|||
receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
|
||||
signaling_thread(),
|
||||
new AudioRtpReceiver(worker_thread(), receiver_id, {}));
|
||||
NoteUsageEvent(UsageEvent::AUDIO_ADDED);
|
||||
} else {
|
||||
RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
|
||||
receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
|
||||
signaling_thread(),
|
||||
new VideoRtpReceiver(worker_thread(), receiver_id, {}));
|
||||
NoteUsageEvent(UsageEvent::VIDEO_ADDED);
|
||||
}
|
||||
return receiver;
|
||||
}
|
||||
|
@ -1711,7 +1715,7 @@ PeerConnection::CreateDataChannel(
|
|||
if (data_channel_type() == cricket::DCT_RTP || first_datachannel) {
|
||||
observer_->OnRenegotiationNeeded();
|
||||
}
|
||||
|
||||
NoteUsageEvent(UsageEvent::DATA_ADDED);
|
||||
return DataChannelProxy::Create(signaling_thread(), channel.get());
|
||||
}
|
||||
|
||||
|
@ -1991,6 +1995,7 @@ void PeerConnection::SetLocalDescription(
|
|||
// Make UMA notes about what was agreed to.
|
||||
ReportNegotiatedSdpSemantics(*local_description());
|
||||
}
|
||||
NoteUsageEvent(UsageEvent::SET_LOCAL_DESCRIPTION_CALLED);
|
||||
}
|
||||
|
||||
RTCError PeerConnection::ApplyLocalDescription(
|
||||
|
@ -2233,6 +2238,7 @@ void PeerConnection::SetRemoteDescription(
|
|||
}
|
||||
|
||||
observer->OnSetRemoteDescriptionComplete(RTCError::OK());
|
||||
NoteUsageEvent(UsageEvent::SET_REMOTE_DESCRIPTION_CALLED);
|
||||
}
|
||||
|
||||
RTCError PeerConnection::ApplyRemoteDescription(
|
||||
|
@ -2899,6 +2905,13 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration,
|
|||
if (parse_error != RTCErrorType::NONE) {
|
||||
return SafeSetError(parse_error, error);
|
||||
}
|
||||
// Note if STUN or TURN servers were supplied.
|
||||
if (!stun_servers.empty()) {
|
||||
NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
|
||||
}
|
||||
if (!turn_servers.empty()) {
|
||||
NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
|
||||
}
|
||||
|
||||
// In theory this shouldn't fail.
|
||||
if (!network_thread()->Invoke<bool>(
|
||||
|
@ -2958,6 +2971,7 @@ bool PeerConnection::AddIceCandidate(
|
|||
RTC_LOG(LS_ERROR) << "AddIceCandidate: Candidate cannot be used.";
|
||||
return false;
|
||||
}
|
||||
NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
|
||||
|
||||
if (ready) {
|
||||
return UseCandidate(ice_candidate);
|
||||
|
@ -3224,6 +3238,7 @@ void PeerConnection::Close() {
|
|||
stats_->UpdateStats(kStatsOutputLevelStandard);
|
||||
|
||||
ChangeSignalingState(PeerConnectionInterface::kClosed);
|
||||
NoteUsageEvent(UsageEvent::CLOSE_CALLED);
|
||||
|
||||
for (auto transceiver : transceivers_) {
|
||||
transceiver->Stop();
|
||||
|
@ -3257,6 +3272,7 @@ void PeerConnection::Close() {
|
|||
// The event log must outlive call (and any other object that uses it).
|
||||
event_log_.reset();
|
||||
});
|
||||
ReportUsagePattern();
|
||||
}
|
||||
|
||||
void PeerConnection::OnMessage(rtc::Message* msg) {
|
||||
|
@ -3335,6 +3351,7 @@ void PeerConnection::CreateAudioReceiver(
|
|||
signaling_thread(), audio_receiver);
|
||||
GetAudioTransceiver()->internal()->AddReceiver(receiver);
|
||||
observer_->OnAddTrack(receiver, std::move(streams));
|
||||
NoteUsageEvent(UsageEvent::AUDIO_ADDED);
|
||||
}
|
||||
|
||||
void PeerConnection::CreateVideoReceiver(
|
||||
|
@ -3350,6 +3367,7 @@ void PeerConnection::CreateVideoReceiver(
|
|||
signaling_thread(), video_receiver);
|
||||
GetVideoTransceiver()->internal()->AddReceiver(receiver);
|
||||
observer_->OnAddTrack(receiver, std::move(streams));
|
||||
NoteUsageEvent(UsageEvent::VIDEO_ADDED);
|
||||
}
|
||||
|
||||
// TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote
|
||||
|
@ -3485,6 +3503,7 @@ void PeerConnection::OnIceCandidate(
|
|||
if (IsClosed()) {
|
||||
return;
|
||||
}
|
||||
NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
|
||||
observer_->OnIceCandidate(candidate.get());
|
||||
}
|
||||
|
||||
|
@ -5223,6 +5242,7 @@ void PeerConnection::OnTransportControllerConnectionState(
|
|||
RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
|
||||
"all transports are writable.";
|
||||
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
|
||||
NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
|
||||
break;
|
||||
case cricket::kIceConnectionCompleted:
|
||||
RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
|
||||
|
@ -5234,6 +5254,7 @@ void PeerConnection::OnTransportControllerConnectionState(
|
|||
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
|
||||
}
|
||||
SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
|
||||
NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
|
||||
if (metrics_observer()) {
|
||||
ReportTransportStats();
|
||||
}
|
||||
|
@ -5874,6 +5895,19 @@ void PeerConnection::ReportSdpFormatReceived(
|
|||
kSdpFormatReceivedMax);
|
||||
}
|
||||
|
||||
void PeerConnection::NoteUsageEvent(UsageEvent event) {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
usage_event_accumulator_ |= static_cast<int>(event);
|
||||
}
|
||||
|
||||
void PeerConnection::ReportUsagePattern() const {
|
||||
RTC_DLOG(LS_INFO) << "Usage signature is " << usage_event_accumulator_;
|
||||
if (uma_observer_) {
|
||||
uma_observer_->IncrementSparseEnumCounter(kEnumCounterUsagePattern,
|
||||
usage_event_accumulator_);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnection::ReportNegotiatedSdpSemantics(
|
||||
const SessionDescriptionInterface& answer) {
|
||||
if (!uma_observer_) {
|
||||
|
|
|
@ -55,6 +55,20 @@ class PeerConnection : public PeerConnectionInternal,
|
|||
public rtc::MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
enum class UsageEvent : int {
|
||||
TURN_SERVER_ADDED = 0x01,
|
||||
STUN_SERVER_ADDED = 0x02,
|
||||
DATA_ADDED = 0x04,
|
||||
AUDIO_ADDED = 0x08,
|
||||
VIDEO_ADDED = 0x10,
|
||||
SET_LOCAL_DESCRIPTION_CALLED = 0x20,
|
||||
SET_REMOTE_DESCRIPTION_CALLED = 0x40,
|
||||
CANDIDATE_COLLECTED = 0x80,
|
||||
REMOTE_CANDIDATE_ADDED = 0x100,
|
||||
ICE_STATE_CONNECTED = 0x200,
|
||||
CLOSE_CALLED = 0x400
|
||||
};
|
||||
|
||||
explicit PeerConnection(PeerConnectionFactory* factory,
|
||||
std::unique_ptr<RtcEventLog> event_log,
|
||||
std::unique_ptr<Call> call);
|
||||
|
@ -857,6 +871,9 @@ class PeerConnection : public PeerConnectionInternal,
|
|||
void ReportNegotiatedCiphers(const cricket::TransportStats& stats,
|
||||
const std::set<cricket::MediaType>& media_types);
|
||||
|
||||
void NoteUsageEvent(UsageEvent event);
|
||||
void ReportUsagePattern() const;
|
||||
|
||||
void OnSentPacket_w(const rtc::SentPacket& sent_packet);
|
||||
|
||||
const std::string GetTransportName(const std::string& content_name);
|
||||
|
@ -999,6 +1016,8 @@ class PeerConnection : public PeerConnectionInternal,
|
|||
// Member variables for caching global options.
|
||||
cricket::AudioOptions audio_options_;
|
||||
cricket::VideoOptions video_options_;
|
||||
|
||||
int usage_event_accumulator_ = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -173,6 +173,14 @@ int FindFirstMediaStatsIndexByKind(
|
|||
return -1;
|
||||
}
|
||||
|
||||
int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
|
||||
int signature = 0;
|
||||
for (const auto it : events) {
|
||||
signature |= static_cast<int>(it);
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
class SignalingMessageReceiver {
|
||||
public:
|
||||
virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
|
||||
|
@ -4467,6 +4475,38 @@ TEST_P(PeerConnectionIntegrationInteropTest,
|
|||
ASSERT_TRUE(ExpectNewFrames(media_expectations));
|
||||
}
|
||||
|
||||
// Test getting the usage fingerprint for a simple test case.
|
||||
TEST_P(PeerConnectionIntegrationTest, UsageFingerprintHistogram) {
|
||||
ASSERT_TRUE(CreatePeerConnectionWrappers());
|
||||
ConnectFakeSignaling();
|
||||
// Register UMA observer before signaling begins.
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
|
||||
new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
caller()->pc()->RegisterUMAObserver(caller_observer);
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver> callee_observer =
|
||||
new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
callee()->pc()->RegisterUMAObserver(callee_observer);
|
||||
caller()->AddAudioTrack();
|
||||
caller()->AddVideoTrack();
|
||||
caller()->CreateAndSetAndSignalOffer();
|
||||
ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
|
||||
caller()->pc()->Close();
|
||||
callee()->pc()->Close();
|
||||
int expected_fingerprint = MakeUsageFingerprint(
|
||||
{PeerConnection::UsageEvent::AUDIO_ADDED,
|
||||
PeerConnection::UsageEvent::VIDEO_ADDED,
|
||||
PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
|
||||
PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
|
||||
PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
|
||||
PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
|
||||
PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
|
||||
PeerConnection::UsageEvent::CLOSE_CALLED});
|
||||
EXPECT_TRUE(caller_observer->ExpectOnlySingleEnumCount(
|
||||
webrtc::kEnumCounterUsagePattern, expected_fingerprint));
|
||||
EXPECT_TRUE(callee_observer->ExpectOnlySingleEnumCount(
|
||||
webrtc::kEnumCounterUsagePattern, expected_fingerprint));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
PeerConnectionIntegrationTest,
|
||||
PeerConnectionIntegrationInteropTest,
|
||||
|
|
Loading…
Reference in a new issue