Commit af5c23c7 authored by Henrik Boström's avatar Henrik Boström Committed by Commit Bot

MediaStreamTrackMetrics simplified to observe tracks, not streams.

Prior to this CL, MediaStreamTrackMetrics hooked up to streams, tracking
not only all of the streams' tracks (CONNECTED/DISCONNECTED) but also
any tracks that might be added or removed from the stream.

This has not been necessary to do for a long time, since the RTP Media
APIs are track-based, not stream-based, and the legacy
addStream()-streams are shimmed on top of addTrack(). Adding a track to
such a stream causes addTrack(), and there is no need for the
MediaStreamTrackMetrics class to observe the streams.

With this CL, MediaStreamTrackMetrics only care about tracks (direction,
kind and id). This also covers the Unified Plan use case of tracks not
necessarily belonging to any stream.

There is room for improvements in this area, such as counting tracks
added through replaceTrack(), but that should be handled separately.
This CL removes the dependency on streams which unblocks
RTCRtpTransceiver/Unified Plan work.

Bug: 810708, 777617
Change-Id: I347e729560717be83b7b1a3571f25a8497d65e46
Reviewed-on: https://chromium-review.googlesource.com/1117691Reviewed-by: default avatarHarald Alvestrand <hta@chromium.org>
Commit-Queue: Henrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572521}
parent d769acbd
......@@ -5,7 +5,6 @@
#include "content/renderer/media/webrtc/media_stream_track_metrics.h"
#include <inttypes.h>
#include <set>
#include <string>
#include "base/md5.h"
......@@ -14,133 +13,44 @@
#include "content/public/common/service_names.mojom.h"
#include "content/renderer/render_thread_impl.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
using webrtc::AudioTrackVector;
using webrtc::MediaStreamInterface;
using webrtc::MediaStreamTrackInterface;
using webrtc::PeerConnectionInterface;
using webrtc::VideoTrackVector;
namespace content {
namespace {
typedef std::set<std::string> IdSet;
template <class T>
IdSet GetTrackIds(const std::vector<rtc::scoped_refptr<T>>& tracks) {
IdSet track_ids;
for (const auto& track : tracks)
track_ids.insert(track->id());
return track_ids;
}
// TODO(tommi): Consolidate this and TrackObserver since these implementations
// are fundamentally achieving the same thing (aside from specific logic inside
// the OnChanged callbacks).
class MediaStreamObserver
: public base::RefCountedThreadSafe<MediaStreamObserver>,
public webrtc::ObserverInterface {
public:
typedef base::Callback<
void(const IdSet& audio_track_ids, const IdSet& video_track_ids)>
OnChangedCallback;
MediaStreamObserver(
const OnChangedCallback& callback,
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
webrtc::MediaStreamInterface* stream)
: main_thread_(main_thread), stream_(stream), callback_(callback) {
signaling_thread_.DetachFromThread();
stream_->RegisterObserver(this);
}
const scoped_refptr<webrtc::MediaStreamInterface>& stream() const {
DCHECK(main_thread_->BelongsToCurrentThread());
return stream_;
}
void Unregister() {
DCHECK(main_thread_->BelongsToCurrentThread());
callback_.Reset();
stream_->UnregisterObserver(this);
stream_ = nullptr;
}
private:
friend class base::RefCountedThreadSafe<MediaStreamObserver>;
~MediaStreamObserver() override {
DCHECK(!stream_.get()) << "must have been unregistered before deleting";
}
// webrtc::ObserverInterface implementation.
void OnChanged() override {
DCHECK(signaling_thread_.CalledOnValidThread());
main_thread_->PostTask(
FROM_HERE, base::BindOnce(&MediaStreamObserver::OnChangedOnMainThread,
this, GetTrackIds(stream_->GetAudioTracks()),
GetTrackIds(stream_->GetVideoTracks())));
}
void OnChangedOnMainThread(const IdSet& audio_track_ids,
const IdSet& video_track_ids) {
DCHECK(main_thread_->BelongsToCurrentThread());
if (!callback_.is_null())
callback_.Run(audio_track_ids, video_track_ids);
}
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
scoped_refptr<webrtc::MediaStreamInterface> stream_;
OnChangedCallback callback_; // Only touched on the main thread.
base::ThreadChecker signaling_thread_;
};
} // namespace
class MediaStreamTrackMetricsObserver {
public:
MediaStreamTrackMetricsObserver(
MediaStreamTrackMetrics::StreamType stream_type,
MediaStreamInterface* stream,
MediaStreamTrackMetrics* owner);
MediaStreamTrackMetricsObserver(MediaStreamTrackMetrics::Direction direction,
MediaStreamTrackMetrics::Kind kind,
std::string track_id,
MediaStreamTrackMetrics* owner);
~MediaStreamTrackMetricsObserver();
// Sends begin/end messages for all tracks currently tracked.
void SendLifetimeMessages(MediaStreamTrackMetrics::LifetimeEvent event);
// Sends begin/end messages for the track if not already reported.
void SendLifetimeMessageForTrack(
MediaStreamTrackMetrics::LifetimeEvent event);
MediaStreamInterface* stream() {
MediaStreamTrackMetrics::Direction direction() {
DCHECK(thread_checker_.CalledOnValidThread());
return observer_->stream().get();
return direction_;
}
MediaStreamTrackMetrics::StreamType stream_type() {
MediaStreamTrackMetrics::Kind kind() {
DCHECK(thread_checker_.CalledOnValidThread());
return stream_type_;
return kind_;
}
private:
void OnChanged(const IdSet& audio_track_ids, const IdSet& video_track_ids);
void ReportAddedAndRemovedTracks(
const IdSet& new_ids,
const IdSet& old_ids,
MediaStreamTrackMetrics::TrackType track_type);
// Sends a lifetime message for the given tracks. OK to call with an
// empty |ids|, in which case the method has no side effects.
void ReportTracks(const IdSet& ids,
MediaStreamTrackMetrics::TrackType track_type,
MediaStreamTrackMetrics::LifetimeEvent event);
std::string track_id() const {
DCHECK(thread_checker_.CalledOnValidThread());
return track_id_;
}
private:
// False until start/end of lifetime messages have been sent.
bool has_reported_start_;
bool has_reported_end_;
// IDs of audio and video tracks in the stream being observed.
IdSet audio_track_ids_;
IdSet video_track_ids_;
MediaStreamTrackMetrics::StreamType stream_type_;
scoped_refptr<MediaStreamObserver> observer_;
MediaStreamTrackMetrics::Direction direction_;
MediaStreamTrackMetrics::Kind kind_;
std::string track_id_;
// Non-owning.
MediaStreamTrackMetrics* owner_;
......@@ -151,47 +61,46 @@ namespace {
// Used with std::find_if.
struct ObserverFinder {
ObserverFinder(MediaStreamTrackMetrics::StreamType stream_type,
MediaStreamInterface* stream)
: stream_type(stream_type), stream_(stream) {}
ObserverFinder(MediaStreamTrackMetrics::Direction direction,
MediaStreamTrackMetrics::Kind kind,
const std::string& track_id)
: direction_(direction), kind_(kind), track_id_(track_id) {}
bool operator()(
const std::unique_ptr<MediaStreamTrackMetricsObserver>& observer) {
return stream_ == observer->stream() &&
stream_type == observer->stream_type();
return direction_ == observer->direction() && kind_ == observer->kind() &&
track_id_ == observer->track_id();
}
MediaStreamTrackMetrics::StreamType stream_type;
MediaStreamInterface* stream_;
MediaStreamTrackMetrics::Direction direction_;
MediaStreamTrackMetrics::Kind kind_;
std::string track_id_;
};
} // namespace
MediaStreamTrackMetricsObserver::MediaStreamTrackMetricsObserver(
MediaStreamTrackMetrics::StreamType stream_type,
MediaStreamInterface* stream,
MediaStreamTrackMetrics::Direction direction,
MediaStreamTrackMetrics::Kind kind,
std::string track_id,
MediaStreamTrackMetrics* owner)
: has_reported_start_(false),
has_reported_end_(false),
audio_track_ids_(GetTrackIds(stream->GetAudioTracks())),
video_track_ids_(GetTrackIds(stream->GetVideoTracks())),
stream_type_(stream_type),
observer_(new MediaStreamObserver(
base::Bind(&MediaStreamTrackMetricsObserver::OnChanged,
base::Unretained(this)),
base::ThreadTaskRunnerHandle::Get(),
stream)),
direction_(direction),
kind_(kind),
track_id_(std::move(track_id)),
owner_(owner) {
DCHECK(owner);
}
MediaStreamTrackMetricsObserver::~MediaStreamTrackMetricsObserver() {
DCHECK(thread_checker_.CalledOnValidThread());
observer_->Unregister();
SendLifetimeMessages(MediaStreamTrackMetrics::DISCONNECTED);
SendLifetimeMessageForTrack(
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected);
}
void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
void MediaStreamTrackMetricsObserver::SendLifetimeMessageForTrack(
MediaStreamTrackMetrics::LifetimeEvent event) {
DCHECK(thread_checker_.CalledOnValidThread());
if (event == MediaStreamTrackMetrics::CONNECTED) {
if (event == MediaStreamTrackMetrics::LifetimeEvent::kConnected) {
// Both ICE CONNECTED and COMPLETED can trigger the first
// start-of-life event, so we only report the first.
if (has_reported_start_)
......@@ -199,7 +108,7 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
DCHECK(!has_reported_start_ && !has_reported_end_);
has_reported_start_ = true;
} else {
DCHECK(event == MediaStreamTrackMetrics::DISCONNECTED);
DCHECK(event == MediaStreamTrackMetrics::LifetimeEvent::kDisconnected);
// We only report the first end-of-life event, since there are
// several cases where end-of-life can be reached. We also don't
......@@ -209,10 +118,9 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
has_reported_end_ = true;
}
ReportTracks(audio_track_ids_, MediaStreamTrackMetrics::AUDIO_TRACK, event);
ReportTracks(video_track_ids_, MediaStreamTrackMetrics::VIDEO_TRACK, event);
owner_->SendLifetimeMessage(track_id_, kind_, event, direction_);
if (event == MediaStreamTrackMetrics::DISCONNECTED) {
if (event == MediaStreamTrackMetrics::LifetimeEvent::kDisconnected) {
// After disconnection, we can get reconnected, so we need to
// forget that we've sent lifetime events, while retaining all
// other state.
......@@ -222,76 +130,33 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
}
}
void MediaStreamTrackMetricsObserver::OnChanged(
const IdSet& audio_track_ids, const IdSet& video_track_ids) {
DCHECK(thread_checker_.CalledOnValidThread());
// We only report changes after our initial report, and never after
// our last report.
if (has_reported_start_ && !has_reported_end_) {
ReportAddedAndRemovedTracks(audio_track_ids,
audio_track_ids_,
MediaStreamTrackMetrics::AUDIO_TRACK);
ReportAddedAndRemovedTracks(video_track_ids,
video_track_ids_,
MediaStreamTrackMetrics::VIDEO_TRACK);
}
// We always update our sets of tracks.
audio_track_ids_ = audio_track_ids;
video_track_ids_ = video_track_ids;
}
void MediaStreamTrackMetricsObserver::ReportAddedAndRemovedTracks(
const IdSet& new_ids,
const IdSet& old_ids,
MediaStreamTrackMetrics::TrackType track_type) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(has_reported_start_ && !has_reported_end_);
IdSet added_tracks = base::STLSetDifference<IdSet>(new_ids, old_ids);
IdSet removed_tracks = base::STLSetDifference<IdSet>(old_ids, new_ids);
ReportTracks(added_tracks, track_type, MediaStreamTrackMetrics::CONNECTED);
ReportTracks(
removed_tracks, track_type, MediaStreamTrackMetrics::DISCONNECTED);
}
void MediaStreamTrackMetricsObserver::ReportTracks(
const IdSet& ids,
MediaStreamTrackMetrics::TrackType track_type,
MediaStreamTrackMetrics::LifetimeEvent event) {
DCHECK(thread_checker_.CalledOnValidThread());
for (IdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
owner_->SendLifetimeMessage(*it, track_type, event, stream_type_);
}
}
MediaStreamTrackMetrics::MediaStreamTrackMetrics()
: ice_state_(webrtc::PeerConnectionInterface::kIceConnectionNew) {}
MediaStreamTrackMetrics::~MediaStreamTrackMetrics() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
for (const auto& observer : observers_) {
observer->SendLifetimeMessages(DISCONNECTED);
observer->SendLifetimeMessageForTrack(LifetimeEvent::kDisconnected);
}
}
void MediaStreamTrackMetrics::AddStream(StreamType type,
MediaStreamInterface* stream) {
void MediaStreamTrackMetrics::AddTrack(Direction direction,
Kind kind,
const std::string& track_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
observers_.push_back(
std::make_unique<MediaStreamTrackMetricsObserver>(type, stream, this));
observers_.push_back(std::make_unique<MediaStreamTrackMetricsObserver>(
direction, kind, std::move(track_id), this));
SendLifeTimeMessageDependingOnIceState(observers_.back().get());
}
void MediaStreamTrackMetrics::RemoveStream(StreamType type,
MediaStreamInterface* stream) {
void MediaStreamTrackMetrics::RemoveTrack(Direction direction,
Kind kind,
const std::string& track_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = std::find_if(observers_.begin(), observers_.end(),
ObserverFinder(type, stream));
ObserverFinder(direction, kind, track_id));
if (it == observers_.end()) {
// Since external apps could call removeStream with a stream they
// Since external apps could call removeTrack() with a stream they
// never added, this can happen without it being an error.
return;
}
......@@ -300,40 +165,41 @@ void MediaStreamTrackMetrics::RemoveStream(StreamType type,
}
void MediaStreamTrackMetrics::IceConnectionChange(
PeerConnectionInterface::IceConnectionState new_state) {
webrtc::PeerConnectionInterface::IceConnectionState new_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ice_state_ = new_state;
for (const auto& observer : observers_) {
SendLifeTimeMessageDependingOnIceState(observer.get());
}
}
void MediaStreamTrackMetrics::SendLifeTimeMessageDependingOnIceState(
MediaStreamTrackMetricsObserver* observer) {
// There is a state transition diagram for these states at
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceConnectionState
switch (ice_state_) {
case PeerConnectionInterface::kIceConnectionConnected:
case PeerConnectionInterface::kIceConnectionCompleted:
observer->SendLifetimeMessages(CONNECTED);
case webrtc::PeerConnectionInterface::kIceConnectionConnected:
case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
observer->SendLifetimeMessageForTrack(LifetimeEvent::kConnected);
break;
case PeerConnectionInterface::kIceConnectionFailed:
// We don't really need to handle FAILED (it is only supposed
// to be preceded by CHECKING so we wouldn't yet have sent a
// lifetime message) but we might as well use belt and
// suspenders and handle it the same as the other "end call"
// states. It will be ignored anyway if the call is not
// already connected.
case PeerConnectionInterface::kIceConnectionNew:
// It's a bit weird to count NEW as an end-lifetime event, but
// it's possible to transition directly from a connected state
// (CONNECTED or COMPLETED) to NEW, which can then be followed
// by a new connection. The observer will ignore the end
// lifetime event if it was not preceded by a begin-lifetime
// event.
case PeerConnectionInterface::kIceConnectionDisconnected:
case PeerConnectionInterface::kIceConnectionClosed:
observer->SendLifetimeMessages(DISCONNECTED);
case webrtc::PeerConnectionInterface::kIceConnectionFailed:
// We don't really need to handle FAILED (it is only supposed
// to be preceded by CHECKING so we wouldn't yet have sent a
// lifetime message) but we might as well use belt and
// suspenders and handle it the same as the other "end call"
// states. It will be ignored anyway if the call is not
// already connected.
case webrtc::PeerConnectionInterface::kIceConnectionNew:
// It's a bit weird to count NEW as an end-lifetime event, but
// it's possible to transition directly from a connected state
// (CONNECTED or COMPLETED) to NEW, which can then be followed
// by a new connection. The observer will ignore the end
// lifetime event if it was not preceded by a begin-lifetime
// event.
case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
case webrtc::PeerConnectionInterface::kIceConnectionClosed:
observer->SendLifetimeMessageForTrack(LifetimeEvent::kDisconnected);
break;
default:
......@@ -345,28 +211,28 @@ void MediaStreamTrackMetrics::SendLifeTimeMessageDependingOnIceState(
}
void MediaStreamTrackMetrics::SendLifetimeMessage(const std::string& track_id,
TrackType track_type,
Kind kind,
LifetimeEvent event,
StreamType stream_type) {
Direction direction) {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
// |render_thread| can be NULL in certain cases when running as part
// |of a unit test.
if (render_thread) {
if (event == CONNECTED) {
if (event == LifetimeEvent::kConnected) {
GetMediaStreamTrackMetricsHost()->AddTrack(
MakeUniqueId(track_id, stream_type), track_type == AUDIO_TRACK,
stream_type == RECEIVED_STREAM);
MakeUniqueId(track_id, direction), kind == Kind::kAudio,
direction == Direction::kReceive);
} else {
DCHECK_EQ(DISCONNECTED, event);
DCHECK_EQ(LifetimeEvent::kDisconnected, event);
GetMediaStreamTrackMetricsHost()->RemoveTrack(
MakeUniqueId(track_id, stream_type));
MakeUniqueId(track_id, direction));
}
}
}
uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
const std::string& track_id,
StreamType stream_type) {
Direction direction) {
// We use a hash over the |track| pointer and the PeerConnection ID,
// plus a boolean flag indicating whether the track is remote (since
// you might conceivably have a remote track added back as a sent
......@@ -376,10 +242,8 @@ uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
// no longer be considered), just one with virtually zero chance of
// collisions when faced with non-malicious data.
std::string unique_id_string =
base::StringPrintf("%" PRIu64 " %s %d",
pc_id,
track_id.c_str(),
stream_type == RECEIVED_STREAM ? 1 : 0);
base::StringPrintf("%" PRIu64 " %s %d", pc_id, track_id.c_str(),
direction == Direction::kReceive ? 1 : 0);
base::MD5Context ctx;
base::MD5Init(&ctx);
......@@ -392,10 +256,10 @@ uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
}
uint64_t MediaStreamTrackMetrics::MakeUniqueId(const std::string& track_id,
StreamType stream_type) {
Direction direction) {
return MakeUniqueIdImpl(
reinterpret_cast<uint64_t>(reinterpret_cast<void*>(this)), track_id,
stream_type);
direction);
}
mojom::MediaStreamTrackMetricsHostPtr&
......
......@@ -15,10 +15,6 @@
#include "content/common/media/media_stream.mojom.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
namespace webrtc {
class MediaStreamInterface;
}
namespace content {
class MediaStreamTrackMetricsObserver;
......@@ -36,19 +32,16 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
explicit MediaStreamTrackMetrics();
~MediaStreamTrackMetrics();
enum StreamType { SENT_STREAM, RECEIVED_STREAM };
enum TrackType { AUDIO_TRACK, VIDEO_TRACK };
enum LifetimeEvent { CONNECTED, DISCONNECTED };
enum class Direction { kSend, kReceive };
enum class Kind { kAudio, kVideo };
enum class LifetimeEvent { kConnected, kDisconnected };
// Starts tracking lifetimes of all the tracks in |stream| and any
// tracks added or removed to/from the stream until |RemoveStream|
// is called or this object's lifetime ends.
void AddStream(StreamType type, webrtc::MediaStreamInterface* stream);
// Starts tracking the lifetime of the track until |RemoveTrack| is called
// or this object's lifetime ends.
void AddTrack(Direction direction, Kind kind, const std::string& track_id);
// Stops tracking lifetimes of tracks in |stream|.
void RemoveStream(StreamType type, webrtc::MediaStreamInterface* stream);
// Stops tracking the lifetime of the track.
void RemoveTrack(Direction direction, Kind kind, const std::string& track_id);
// Called to indicate changes in the ICE connection state for the
// PeerConnection this object is associated with. Used to generate
......@@ -71,9 +64,9 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
// PeerConnection), false for local streams (sent over a
// PeerConnection).
virtual void SendLifetimeMessage(const std::string& track_id,
TrackType track_type,
Kind kind,
LifetimeEvent lifetime_event,
StreamType stream_type);
Direction direction);
protected:
// Calls SendLifetimeMessage for |observer| depending on |ice_state_|.
......@@ -86,12 +79,12 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
// is a one-to-one relationship).
uint64_t MakeUniqueIdImpl(uint64_t pc_id,
const std::string& track,
StreamType stream_type);
Direction direction);
private:
// Make a unique ID for the given track, that is valid while the
// track object and the PeerConnection it is attached to both exist.
uint64_t MakeUniqueId(const std::string& track, StreamType stream_type);
uint64_t MakeUniqueId(const std::string& track_id, Direction direction);
mojom::MediaStreamTrackMetricsHostPtr& GetMediaStreamTrackMetricsHost();
......
......@@ -78,8 +78,7 @@ class MockMediaStreamTrackMetrics : public MediaStreamTrackMetrics {
virtual ~MockMediaStreamTrackMetrics() {}
MOCK_METHOD4(SendLifetimeMessage,
void(const std::string&, TrackType, LifetimeEvent, StreamType));
void(const std::string&, Kind, LifetimeEvent, Direction));
using MediaStreamTrackMetrics::MakeUniqueIdImpl;
};
......@@ -170,88 +169,82 @@ TEST_F(MediaStreamTrackMetricsTest, MakeUniqueId) {
// Lower 32 bits the same, upper 32 differ.
EXPECT_NE(
metrics_->MakeUniqueIdImpl(
0x1000000000000001, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
metrics_->MakeUniqueIdImpl(
0x2000000000000001, "x", MediaStreamTrackMetrics::RECEIVED_STREAM));
metrics_->MakeUniqueIdImpl(0x1000000000000001, "x",
MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(0x2000000000000001, "x",
MediaStreamTrackMetrics::Direction::kReceive));
// Track ID differs.
EXPECT_NE(metrics_->MakeUniqueIdImpl(
42, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
42, "x", MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(
42, "y", MediaStreamTrackMetrics::RECEIVED_STREAM));
42, "y", MediaStreamTrackMetrics::Direction::kReceive));
// Remove vs. local track differs.
EXPECT_NE(metrics_->MakeUniqueIdImpl(
42, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
42, "x", MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(
42, "x", MediaStreamTrackMetrics::SENT_STREAM));
42, "x", MediaStreamTrackMetrics::Direction::kSend));
}
TEST_F(MediaStreamTrackMetricsTest, BasicRemoteStreams) {
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
stream_->AddTrack(audio.get());
stream_->AddTrack(video.get());
metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kVideo, "video");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kReceive));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kReceive));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
}
TEST_F(MediaStreamTrackMetricsTest, BasicLocalStreams) {
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
stream_->AddTrack(audio.get());
stream_->AddTrack(video.get());
metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kVideo, "video");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
}
......@@ -259,341 +252,226 @@ TEST_F(MediaStreamTrackMetricsTest, LocalStreamAddedAferIceConnect) {
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
stream_->AddTrack(audio.get());
stream_->AddTrack(video.get());
metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamAddedAferIceConnect) {
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
stream_->AddTrack(audio.get());
stream_->AddTrack(video.get());
metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamTrackAdded) {
scoped_refptr<MockAudioTrackInterface> initial(MakeAudioTrack("initial"));
scoped_refptr<MockAudioTrackInterface> added(MakeAudioTrack("added"));
stream_->AddTrack(initial.get());
metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("initial",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("added",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
AddAudioTrack(added.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("initial",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("added",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kReceive));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamTrackRemoved) {
scoped_refptr<MockAudioTrackInterface> first(MakeAudioTrack("first"));
scoped_refptr<MockAudioTrackInterface> second(MakeAudioTrack("second"));
stream_->AddTrack(first.get());
stream_->AddTrack(second.get());
metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("first",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("second",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "first");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "second");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"first", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"second", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("first",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
stream_->RemoveTrack(first.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("second",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("first", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "first");
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("second", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamModificationsBeforeAndAfter) {
scoped_refptr<MockAudioTrackInterface> first(MakeAudioTrack("first"));
scoped_refptr<MockAudioTrackInterface> second(MakeAudioTrack("second"));
stream_->AddTrack(first.get());
metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
// This gets added after we start observing, but no lifetime message
// should be sent at this point since the call is not connected. It
// should get sent only once it gets connected.
AddAudioTrack(second.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("first",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("second",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
TEST_F(MediaStreamTrackMetricsTest, RemoveAfterDisconnect) {
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("first",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("second",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
// This happens after the call is disconnected so no lifetime
// message should be sent.
RemoveAudioTrack(first.get());
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamMultipleDisconnects) {
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
stream_->AddTrack(audio.get());
metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
RemoveAudioTrack(audio.get());
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamConnectDisconnectTwice) {
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
stream_->AddTrack(audio.get());
metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
for (size_t i = 0; i < 2; ++i) {
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
}
RemoveAudioTrack(audio.get());
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamRemovedNoDisconnect) {
scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
stream_->AddTrack(audio.get());
stream_->AddTrack(video.get());
metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kVideo, "video");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
metrics_->RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamLargerTest) {
scoped_refptr<MockAudioTrackInterface> audio1(MakeAudioTrack("audio1"));
scoped_refptr<MockAudioTrackInterface> audio2(MakeAudioTrack("audio2"));
scoped_refptr<MockAudioTrackInterface> audio3(MakeAudioTrack("audio3"));
scoped_refptr<MockVideoTrackInterface> video1(MakeVideoTrack("video1"));
scoped_refptr<MockVideoTrackInterface> video2(MakeVideoTrack("video2"));
scoped_refptr<MockVideoTrackInterface> video3(MakeVideoTrack("video3"));
stream_->AddTrack(audio1.get());
stream_->AddTrack(video1.get());
metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio1",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video1",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kVideo, "video");
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio2",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
AddAudioTrack(audio2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video2",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
AddVideoTrack(video2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio1",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
RemoveAudioTrack(audio1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio3",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
AddAudioTrack(audio3.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video3",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
AddVideoTrack(video3.get());
// Add back audio1
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio1",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
AddAudioTrack(audio1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio2",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
RemoveAudioTrack(audio2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video2",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
RemoveVideoTrack(video2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio1",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
RemoveAudioTrack(audio1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video1",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
RemoveVideoTrack(video1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio3",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video3",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
metrics_->RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
// Add back audio
EXPECT_CALL(*metrics_, SendLifetimeMessage(
"audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kConnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kAudio, "audio");
EXPECT_CALL(
*metrics_,
SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
MediaStreamTrackMetrics::Direction::kSend));
metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetrics::Kind::kVideo, "video");
}
} // namespace content
......@@ -893,6 +893,13 @@ SdpSemanticRequested GetSdpSemanticRequested(
return kSdpSemanticRequestedDefault;
}
MediaStreamTrackMetrics::Kind MediaStreamTrackMetricsKind(
const blink::WebMediaStreamTrack& track) {
return track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio
? MediaStreamTrackMetrics::Kind::kAudio
: MediaStreamTrackMetrics::Kind::kVideo;
}
} // namespace
// Implementation of LocalRTCStatsRequest.
......@@ -1826,6 +1833,9 @@ std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
webrtc_streams);
if (!webrtc_sender)
return nullptr;
track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetricsKind(track),
track.Id().Utf8());
DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender)) == rtp_senders_.end());
rtp_senders_.push_back(std::make_unique<RTCRtpSender>(
native_peer_connection_, task_runner_, signaling_thread(),
......@@ -1840,8 +1850,6 @@ std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
if (GetLocalStreamUsageCount(rtp_senders_,
stream_ref->adapter().web_stream()) == 1u) {
PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM,
stream_ref->adapter().webrtc_stream().get());
}
}
return rtp_senders_.back()->ShallowCopy();
......@@ -1850,11 +1858,15 @@ std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
bool RTCPeerConnectionHandler::RemoveTrack(blink::WebRTCRtpSender* web_sender) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::RemoveTrack");
auto web_track = web_sender->Track();
auto it = FindSender(web_sender->Id());
if (it == rtp_senders_.end())
return false;
if (!(*it)->RemoveFromPeerConnection(native_peer_connection_.get()))
return false;
track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
MediaStreamTrackMetricsKind(web_track),
web_track.Id().Utf8());
auto stream_refs = (*it)->stream_refs();
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackRemoveTransceiver(
......@@ -1869,8 +1881,6 @@ bool RTCPeerConnectionHandler::RemoveTrack(blink::WebRTCRtpSender* web_sender) {
if (GetLocalStreamUsageCount(rtp_senders_,
stream_ref->adapter().web_stream()) == 0u) {
PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM,
stream_ref->adapter().webrtc_stream().get());
}
}
return true;
......@@ -2062,7 +2072,10 @@ void RTCPeerConnectionHandler::OnAddRemoteTrack(
remote_stream_adapter_refs) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddRemoteTrack");
auto web_track = remote_track_adapter_ref->web_track();
track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetricsKind(web_track),
web_track.Id().Utf8());
for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) {
// New remote stream?
if (GetRemoteStreamUsageCount(
......@@ -2070,9 +2083,6 @@ void RTCPeerConnectionHandler::OnAddRemoteTrack(
remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) {
// Update metrics.
PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
track_metrics_.AddStream(
MediaStreamTrackMetrics::RECEIVED_STREAM,
remote_stream_adapter_ref->adapter().webrtc_stream().get());
}
}
......@@ -2116,8 +2126,12 @@ void RTCPeerConnectionHandler::OnRemoveRemoteTrack(
nullptr /* sender */, it->second->ShallowCopy() /* receiver */);
}
remote_stream_adapter_refs = it->second->StreamAdapterRefs();
auto receiver = it->second->ShallowCopy();
track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetricsKind(receiver->Track()),
receiver->Track().Id().Utf8());
if (!is_closed_)
client_->DidRemoveRemoteTrack(it->second->ShallowCopy());
client_->DidRemoveRemoteTrack(std::move(receiver));
rtp_receivers_.erase(it);
}
......@@ -2127,9 +2141,6 @@ void RTCPeerConnectionHandler::OnRemoveRemoteTrack(
rtp_receivers_,
remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) {
// Update metrics.
track_metrics_.RemoveStream(
MediaStreamTrackMetrics::RECEIVED_STREAM,
remote_stream_adapter_ref->adapter().webrtc_stream().get());
PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment