Implement OnRemoveTrack and OnRemoveStream for Unified Plan
Also parameterizes the PeerConnection RTP unit tests to test
Unified Plan also.
Bug: webrtc:8587
Change-Id: I7661d9f2ec4b3bce0d2e2979035fa02225e3f118
Reviewed-on: https://webrtc-review.googlesource.com/73284
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23157}
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index 8ffb814..fd57853 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -1098,9 +1098,7 @@
// Triggered when media is received on a new stream from remote peer.
virtual void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) {}
- // Triggered when a remote peer close a stream.
- // Deprecated: This callback will no longer be fired with Unified Plan
- // semantics.
+ // Triggered when a remote peer closes a stream.
virtual void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream) {
}
@@ -1158,14 +1156,13 @@
virtual void OnTrack(
rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {}
- // Called when a receiver is completely removed. This is current (Plan B SDP)
- // behavior that occurs when processing the removal of a remote track, and is
- // called when the receiver is removed and the track is muted. When Unified
- // Plan SDP is supported, transceivers can change direction (and receivers
- // stopped) but receivers are never removed, so this is never called.
+ // Called when signaling indicates that media will no longer be received on a
+ // track.
+ // With Plan B semantics, the given receiver will have been removed from the
+ // PeerConnection and the track muted.
+ // With Unified Plan semantics, the receiver will remain but the transceiver
+ // will have changed direction to either sendonly or inactive.
// https://w3c.github.io/webrtc-pc/#process-remote-track-removal
- // TODO(hbos,deadbeef): When Unified Plan SDP is supported and receivers are
- // no longer removed, deprecate and remove this callback.
// TODO(hbos,deadbeef): Make pure virtual when all subclasses implement it.
virtual void OnRemoveTrack(
rtc::scoped_refptr<RtpReceiverInterface> receiver) {}
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index 54de56c..552bd2f 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -2360,8 +2360,11 @@
if (IsUnifiedPlan()) {
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
- receiving_transceivers;
+ now_receiving_transceivers;
+ std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
+ no_longer_receiving_transceivers;
std::vector<rtc::scoped_refptr<MediaStreamInterface>> added_streams;
+ std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
for (auto transceiver : transceivers_) {
const ContentInfo* content =
FindMediaSectionForTransceiver(transceiver, remote_description());
@@ -2400,8 +2403,9 @@
}
media_streams.push_back(stream);
}
+ // This will add the remote track to the streams.
transceiver->internal()->receiver_internal()->SetStreams(media_streams);
- receiving_transceivers.push_back(transceiver);
+ now_receiving_transceivers.push_back(transceiver);
}
// If direction is sendonly or inactive, and transceiver's current
// direction is neither sendonly nor inactive, process the removal of a
@@ -2411,7 +2415,19 @@
RtpTransceiverDirectionHasRecv(*transceiver->current_direction()))) {
RTC_LOG(LS_INFO) << "Processing the removal of a track for MID="
<< content->name;
+ std::vector<rtc::scoped_refptr<MediaStreamInterface>> media_streams =
+ transceiver->internal()->receiver_internal()->streams();
+ // This will remove the remote track from the streams.
transceiver->internal()->receiver_internal()->SetStreams({});
+ no_longer_receiving_transceivers.push_back(transceiver);
+ // Remove any streams that no longer have tracks.
+ for (auto stream : media_streams) {
+ if (stream->GetAudioTracks().empty() &&
+ stream->GetVideoTracks().empty()) {
+ remote_streams_->RemoveStream(stream);
+ removed_streams.push_back(stream);
+ }
+ }
}
if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
transceiver->internal()->set_current_direction(local_direction);
@@ -2433,7 +2449,7 @@
}
}
// Once all processing has finished, fire off callbacks.
- for (auto transceiver : receiving_transceivers) {
+ for (auto transceiver : now_receiving_transceivers) {
stats_->AddTrack(transceiver->receiver()->track());
observer_->OnTrack(transceiver);
observer_->OnAddTrack(transceiver->receiver(),
@@ -2442,6 +2458,12 @@
for (auto stream : added_streams) {
observer_->OnAddStream(stream);
}
+ for (auto transceiver : no_longer_receiving_transceivers) {
+ observer_->OnRemoveTrack(transceiver->receiver());
+ }
+ for (auto stream : removed_streams) {
+ observer_->OnRemoveStream(stream);
+ }
}
const cricket::ContentInfo* audio_content =
diff --git a/pc/peerconnection_rtp_unittest.cc b/pc/peerconnection_rtp_unittest.cc
index 36fa5c7..f4a174b 100644
--- a/pc/peerconnection_rtp_unittest.cc
+++ b/pc/peerconnection_rtp_unittest.cc
@@ -42,6 +42,7 @@
using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using ::testing::ElementsAre;
using ::testing::UnorderedElementsAre;
+using ::testing::Values;
const uint32_t kDefaultTimeout = 10000u;
@@ -62,10 +63,11 @@
MethodFunctor on_success_;
};
-class PeerConnectionRtpTest : public testing::Test {
+class PeerConnectionRtpBaseTest : public testing::Test {
public:
- PeerConnectionRtpTest()
- : pc_factory_(
+ explicit PeerConnectionRtpBaseTest(SdpSemantics sdp_semantics)
+ : sdp_semantics_(sdp_semantics),
+ pc_factory_(
CreatePeerConnectionFactory(rtc::Thread::Current(),
rtc::Thread::Current(),
rtc::Thread::Current(),
@@ -84,54 +86,87 @@
std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithPlanB() {
RTCConfiguration config;
config.sdp_semantics = SdpSemantics::kPlanB;
- return CreatePeerConnection(config);
+ return CreatePeerConnectionInternal(config);
}
std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithUnifiedPlan() {
RTCConfiguration config;
config.sdp_semantics = SdpSemantics::kUnifiedPlan;
- return CreatePeerConnection(config);
+ return CreatePeerConnectionInternal(config);
}
std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
const RTCConfiguration& config) {
+ RTCConfiguration modified_config = config;
+ modified_config.sdp_semantics = sdp_semantics_;
+ return CreatePeerConnectionInternal(modified_config);
+ }
+
+ protected:
+ const SdpSemantics sdp_semantics_;
+ rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
+
+ private:
+ // Private so that tests don't accidentally bypass the SdpSemantics
+ // adjustment.
+ std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionInternal(
+ const RTCConfiguration& config) {
auto observer = rtc::MakeUnique<MockPeerConnectionObserver>();
auto pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr,
observer.get());
return rtc::MakeUnique<PeerConnectionWrapper>(pc_factory_, pc,
std::move(observer));
}
+};
+class PeerConnectionRtpTest
+ : public PeerConnectionRtpBaseTest,
+ public ::testing::WithParamInterface<SdpSemantics> {
protected:
- rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
+ PeerConnectionRtpTest() : PeerConnectionRtpBaseTest(GetParam()) {}
+};
+
+class PeerConnectionRtpTestPlanB : public PeerConnectionRtpBaseTest {
+ protected:
+ PeerConnectionRtpTestPlanB()
+ : PeerConnectionRtpBaseTest(SdpSemantics::kPlanB) {}
+};
+
+class PeerConnectionRtpTestUnifiedPlan : public PeerConnectionRtpBaseTest {
+ protected:
+ PeerConnectionRtpTestUnifiedPlan()
+ : PeerConnectionRtpBaseTest(SdpSemantics::kUnifiedPlan) {}
};
// These tests cover |webrtc::PeerConnectionObserver| callbacks firing upon
// setting the remote description.
-class PeerConnectionRtpCallbacksTest : public PeerConnectionRtpTest {};
-TEST_F(PeerConnectionRtpCallbacksTest, AddTrackWithoutStreamFiresOnAddTrack) {
+TEST_P(PeerConnectionRtpTest, AddTrackWithoutStreamFiresOnAddTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track")));
+ ASSERT_TRUE(caller->AddAudioTrack("audio_track"));
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
- // Since we are not supporting the no stream case with Plan B, there should be
- // a generated stream, even though we didn't set one with AddTrack.
- auto& add_track_event = callee->observer()->add_track_events_[0];
- ASSERT_EQ(add_track_event.streams.size(), 1u);
- EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
+ const auto& add_track_event = callee->observer()->add_track_events_[0];
EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
+
+ if (sdp_semantics_ == SdpSemantics::kPlanB) {
+ // Since we are not supporting the no stream case with Plan B, there should
+ // be a generated stream, even though we didn't set one with AddTrack.
+ ASSERT_EQ(1u, add_track_event.streams.size());
+ EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
+ } else {
+ EXPECT_EQ(0u, add_track_event.streams.size());
+ }
}
-TEST_F(PeerConnectionRtpCallbacksTest, AddTrackWithStreamFiresOnAddTrack) {
+TEST_P(PeerConnectionRtpTest, AddTrackWithStreamFiresOnAddTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track"),
- {"audio_stream"}));
+ ASSERT_TRUE(caller->AddAudioTrack("audio_track", {"audio_stream"}));
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
@@ -142,14 +177,16 @@
EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
}
-TEST_F(PeerConnectionRtpCallbacksTest,
- RemoveTrackWithoutStreamFiresOnRemoveTrack) {
+TEST_P(PeerConnectionRtpTest, RemoveTrackWithoutStreamFiresOnRemoveTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"), {});
+ auto sender = caller->AddAudioTrack("audio_track", {});
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
+ ASSERT_TRUE(
+ caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
+
EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
@@ -158,36 +195,36 @@
callee->observer()->remove_track_events_);
}
-TEST_F(PeerConnectionRtpCallbacksTest,
- RemoveTrackWithStreamFiresOnRemoveTrack) {
+TEST_P(PeerConnectionRtpTest, RemoveTrackWithStreamFiresOnRemoveTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"),
- {"audio_stream"});
+ auto sender = caller->AddAudioTrack("audio_track", {"audio_stream"});
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
+ ASSERT_TRUE(
+ caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
+
EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
callee->observer()->remove_track_events_);
+ EXPECT_EQ(0u, callee->observer()->remote_streams()->count());
}
-TEST_F(PeerConnectionRtpCallbacksTest,
- RemoveTrackWithSharedStreamFiresOnRemoveTrack) {
+TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamFiresOnRemoveTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
const char kSharedStreamId[] = "shared_audio_stream";
- auto sender1 = caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
- {kSharedStreamId});
- auto sender2 = caller->AddTrack(caller->CreateAudioTrack("audio_track2"),
- {kSharedStreamId});
+ auto sender1 = caller->AddAudioTrack("audio_track1", {kSharedStreamId});
+ auto sender2 = caller->AddAudioTrack("audio_track2", {kSharedStreamId});
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
-
ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
+ ASSERT_TRUE(
+ caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
// Remove "audio_track1".
EXPECT_TRUE(caller->pc()->RemoveTrack(sender1));
@@ -197,6 +234,9 @@
std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
callee->observer()->add_track_events_[0].receiver},
callee->observer()->remove_track_events_);
+ ASSERT_EQ(1u, callee->observer()->remote_streams()->count());
+ ASSERT_TRUE(
+ caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
// Remove "audio_track2".
EXPECT_TRUE(caller->pc()->RemoveTrack(sender2));
@@ -204,28 +244,29 @@
ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
callee->observer()->remove_track_events_);
+ EXPECT_EQ(0u, callee->observer()->remote_streams()->count());
}
// Tests the edge case that if a stream ID changes for a given track that both
// OnRemoveTrack and OnAddTrack is fired.
-TEST_F(PeerConnectionRtpCallbacksTest,
+TEST_F(PeerConnectionRtpTestPlanB,
RemoteStreamIdChangesFiresOnRemoveAndOnAddTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
const char kStreamId1[] = "stream1";
const char kStreamId2[] = "stream2";
- caller->AddTrack(caller->CreateAudioTrack("audio_track1"), {kStreamId1});
+ caller->AddAudioTrack("audio_track1", {kStreamId1});
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
// Change the stream ID of the sender in the session description.
auto offer = caller->CreateOfferAndSetAsLocal();
- auto audio_desc = offer->description()->GetContentDescriptionByName("audio");
+ auto* audio_desc =
+ cricket::GetFirstAudioContentDescription(offer->description());
ASSERT_EQ(audio_desc->mutable_streams().size(), 1u);
audio_desc->mutable_streams()[0].set_stream_ids({kStreamId2});
- ASSERT_TRUE(
- callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
+ ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
EXPECT_EQ(callee->observer()->add_track_events_[1].streams[0]->id(),
@@ -240,11 +281,11 @@
// with receive only transceivers will not call OnTrack. One transceiver is
// created without any stream_ids, while the other is created with multiple
// stream_ids.
-TEST_F(PeerConnectionRtpCallbacksTest, UnifiedPlanAddTransceiverCallsOnTrack) {
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTransceiverCallsOnTrack) {
const std::string kStreamId1 = "video_stream1";
const std::string kStreamId2 = "video_stream2";
- auto caller = CreatePeerConnectionWithUnifiedPlan();
- auto callee = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
RtpTransceiverInit video_transceiver_init;
@@ -272,9 +313,9 @@
// Test that doing additional offer/answer exchanges with no changes to tracks
// will cause no additional OnTrack calls after the tracks have been negotiated.
-TEST_F(PeerConnectionRtpCallbacksTest, UnifiedPlanReofferDoesNotCallOnTrack) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
- auto callee = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, ReofferDoesNotCallOnTrack) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
caller->AddAudioTrack("audio");
callee->AddAudioTrack("audio");
@@ -296,9 +337,9 @@
// Test that OnTrack is called when the transceiver direction changes to send
// the track.
-TEST_F(PeerConnectionRtpCallbacksTest, UnifiedPlanSetDirectionCallsOnTrack) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
- auto callee = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, SetDirectionCallsOnTrack) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
transceiver->SetDirection(RtpTransceiverDirection::kInactive);
@@ -321,10 +362,9 @@
// Test that OnTrack is called twice when a sendrecv call is started, the callee
// changes the direction to inactive, then changes it back to sendrecv.
-TEST_F(PeerConnectionRtpCallbacksTest,
- UnifiedPlanSetDirectionHoldCallsOnTrackTwice) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
- auto callee = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, SetDirectionHoldCallsOnTrackTwice) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
@@ -350,32 +390,77 @@
EXPECT_EQ(2u, callee->observer()->on_track_transceivers_.size());
}
-// These tests examine the state of the peer connection as a result of
-// performing SetRemoteDescription().
-class PeerConnectionRtpObserverTest : public PeerConnectionRtpTest {};
-
-TEST_F(PeerConnectionRtpObserverTest, AddSenderWithoutStreamAddsReceiver) {
+// Test that setting a remote offer twice with no answer in the middle results
+// in OnAddTrack being fired twice, once for each SetRemoteDescription. This
+// happens since the RtpTransceiver's current_direction is only updated when
+// setting the answer.
+// TODO(bugs.webrtc.org/9236): This is spec-compliant but strange behavior.
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ ApplyTwoOffersWithNoAnswerResultsInTwoAddTrackEvents) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track"), {}));
+ caller->AddAudioTrack("audio_track", {});
+
+ ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ ASSERT_EQ(1u, callee->observer()->add_track_events_.size());
+
+ ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_EQ(2u, callee->observer()->add_track_events_.size());
+}
+
+// Test that setting a remote offer twice with no answer in the middle and the
+// track being removed between the two offers results in OnAddTrack being called
+// once the first time and OnRemoveTrack never getting called. This happens
+// since the RtpTransceiver's current_direction is only updated when setting the
+// answer.
+// TODO(bugs.webrtc.org/9236): This is spec-compliant but strange behavior.
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ ApplyTwoOffersWithNoAnswerAndTrackRemovedResultsInNoRemoveTrackEvents) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+
+ auto sender = caller->AddAudioTrack("audio_track", {});
+
+ ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ ASSERT_EQ(1u, callee->observer()->add_track_events_.size());
+
+ caller->pc()->RemoveTrack(sender);
+
+ ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
+ EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
+ EXPECT_EQ(0u, callee->observer()->remove_track_events_.size());
+}
+
+// These tests examine the state of the peer connection as a result of
+// performing SetRemoteDescription().
+
+TEST_P(PeerConnectionRtpTest, AddTrackWithoutStreamAddsReceiver) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
+
+ ASSERT_TRUE(caller->AddAudioTrack("audio_track", {}));
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
auto receiver_added = callee->pc()->GetReceivers()[0];
EXPECT_EQ("audio_track", receiver_added->track()->id());
- // Since we are not supporting the no stream case with Plan B, there should be
- // a generated stream, even though we didn't set one with AddTrack.
- EXPECT_EQ(receiver_added->streams().size(), 1u);
- EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
+
+ if (sdp_semantics_ == SdpSemantics::kPlanB) {
+ // Since we are not supporting the no stream case with Plan B, there should
+ // be a generated stream, even though we didn't set one with AddTrack.
+ ASSERT_EQ(1u, receiver_added->streams().size());
+ EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
+ } else {
+ EXPECT_EQ(0u, receiver_added->streams().size());
+ }
}
-TEST_F(PeerConnectionRtpObserverTest, AddSenderWithStreamAddsReceiver) {
+TEST_P(PeerConnectionRtpTest, AddTrackWithStreamAddsReceiver) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track"),
- {"audio_stream"}));
+ ASSERT_TRUE(caller->AddAudioTrack("audio_track", {"audio_stream"}));
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
@@ -386,97 +471,113 @@
EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
}
-TEST_F(PeerConnectionRtpObserverTest,
- RemoveSenderWithoutStreamRemovesReceiver) {
+TEST_P(PeerConnectionRtpTest, RemoveTrackWithoutStreamRemovesReceiver) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"), {});
+ auto sender = caller->AddAudioTrack("audio_track", {});
ASSERT_TRUE(sender);
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
+
ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
auto receiver = callee->pc()->GetReceivers()[0];
ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
- // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
- // Instead, the transceiver owning the receiver will become inactive.
- EXPECT_EQ(callee->pc()->GetReceivers().size(), 0u);
+ if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
+ // With Unified Plan the receiver stays but the transceiver transitions to
+ // inactive.
+ ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
+ EXPECT_EQ(RtpTransceiverDirection::kInactive,
+ callee->pc()->GetTransceivers()[0]->current_direction());
+ } else {
+ // With Plan B the receiver is removed.
+ ASSERT_EQ(0u, callee->pc()->GetReceivers().size());
+ }
}
-TEST_F(PeerConnectionRtpObserverTest, RemoveSenderWithStreamRemovesReceiver) {
+TEST_P(PeerConnectionRtpTest, RemoveTrackWithStreamRemovesReceiver) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
- auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"),
- {"audio_stream"});
+ auto sender = caller->AddAudioTrack("audio_track", {"audio_stream"});
ASSERT_TRUE(sender);
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
auto receiver = callee->pc()->GetReceivers()[0];
ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
- // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
- // Instead, the transceiver owning the receiver will become inactive.
- EXPECT_EQ(callee->pc()->GetReceivers().size(), 0u);
+ if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
+ // With Unified Plan the receiver stays but the transceiver transitions to
+ // inactive.
+ EXPECT_EQ(1u, callee->pc()->GetReceivers().size());
+ EXPECT_EQ(RtpTransceiverDirection::kInactive,
+ callee->pc()->GetTransceivers()[0]->current_direction());
+ } else {
+ // With Plan B the receiver is removed.
+ EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
+ }
}
-TEST_F(PeerConnectionRtpObserverTest,
- RemoveSenderWithSharedStreamRemovesReceiver) {
+TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamRemovesReceiver) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
const char kSharedStreamId[] = "shared_audio_stream";
- auto sender1 = caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
- {kSharedStreamId});
- auto sender2 = caller->AddTrack(caller->CreateAudioTrack("audio_track2"),
- {kSharedStreamId});
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
-
- ASSERT_EQ(callee->pc()->GetReceivers().size(), 2u);
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver1;
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver2;
- if (callee->pc()->GetReceivers()[0]->track()->id() == "audio_track1") {
- receiver1 = callee->pc()->GetReceivers()[0];
- receiver2 = callee->pc()->GetReceivers()[1];
- } else {
- receiver1 = callee->pc()->GetReceivers()[1];
- receiver2 = callee->pc()->GetReceivers()[0];
- }
- EXPECT_EQ("audio_track1", receiver1->track()->id());
- EXPECT_EQ("audio_track2", receiver2->track()->id());
+ auto sender1 = caller->AddAudioTrack("audio_track1", {kSharedStreamId});
+ auto sender2 = caller->AddAudioTrack("audio_track2", {kSharedStreamId});
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
+ ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
// Remove "audio_track1".
EXPECT_TRUE(caller->pc()->RemoveTrack(sender1));
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
- // Only |receiver2| should remain.
- // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
- // Instead, the transceiver owning the receiver will become inactive.
- EXPECT_EQ(
- std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>>{receiver2},
- callee->pc()->GetReceivers());
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
+
+ if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
+ // With Unified Plan the receiver stays but the transceiver transitions to
+ // inactive.
+ ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
+ auto transceiver = callee->pc()->GetTransceivers()[0];
+ EXPECT_EQ("audio_track1", transceiver->receiver()->track()->id());
+ EXPECT_EQ(RtpTransceiverDirection::kInactive,
+ transceiver->current_direction());
+ } else {
+ // With Plan B the receiver is removed.
+ ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
+ EXPECT_EQ("audio_track2", callee->pc()->GetReceivers()[0]->track()->id());
+ }
// Remove "audio_track2".
EXPECT_TRUE(caller->pc()->RemoveTrack(sender2));
- ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
- // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
- // Instead, the transceiver owning the receiver will become inactive.
- EXPECT_EQ(callee->pc()->GetReceivers().size(), 0u);
+ ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
+
+ if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
+ // With Unified Plan the receiver stays but the transceiver transitions to
+ // inactive.
+ ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
+ auto transceiver = callee->pc()->GetTransceivers()[1];
+ EXPECT_EQ("audio_track2", transceiver->receiver()->track()->id());
+ EXPECT_EQ(RtpTransceiverDirection::kInactive,
+ transceiver->current_direction());
+ } else {
+ // With Plan B the receiver is removed.
+ ASSERT_EQ(0u, callee->pc()->GetReceivers().size());
+ }
}
// Invokes SetRemoteDescription() twice in a row without synchronizing the two
// calls and examine the state of the peer connection inside the callbacks to
// ensure that the second call does not occur prematurely, contaminating the
// state of the peer connection of the first callback.
-TEST_F(PeerConnectionRtpObserverTest,
+TEST_F(PeerConnectionRtpTestPlanB,
StatesCorrelateWithSetRemoteDescriptionCall) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
// Create SDP for adding a track and for removing it. This will be used in the
// first and second SetRemoteDescription() calls.
- auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"), {});
+ auto sender = caller->AddAudioTrack("audio_track", {});
auto srd1_sdp = caller->CreateOfferAndSetAsLocal();
EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
auto srd2_sdp = caller->CreateOfferAndSetAsLocal();
@@ -521,9 +622,9 @@
// Tests that a remote track is created with the signaled MSIDs when they are
// communicated with a=msid and no SSRCs are signaled at all (i.e., no a=ssrc
// lines).
-TEST_F(PeerConnectionRtpObserverTest, UnsignaledSsrcCreatesReceiverStreams) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
- auto callee = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, UnsignaledSsrcCreatesReceiverStreams) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
const char kStreamId1[] = "stream1";
const char kStreamId2[] = "stream2";
caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
@@ -555,9 +656,9 @@
// Tests that with Unified Plan if the the stream id changes for a track when
// when setting a new remote description, that the media stream is updated
// appropriately for the receiver.
-TEST_F(PeerConnectionRtpObserverTest, RemoteStreamIdChangesUpdatesReceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
- auto callee = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoteStreamIdChangesUpdatesReceiver) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnection();
const char kStreamId1[] = "stream1";
const char kStreamId2[] = "stream2";
@@ -588,7 +689,7 @@
// remote audio senders, FindSenderInfo didn't find them as unique, because
// it looked up by StreamParam.id, which none had. This meant only one
// AudioRtpReceiver was created, as opposed to one for each remote sender.
-TEST_F(PeerConnectionRtpObserverTest,
+TEST_F(PeerConnectionRtpTestPlanB,
MultipleRemoteSendersWithoutStreamParamIdAddsMultipleReceivers) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
@@ -618,10 +719,9 @@
}
// Tests for the legacy SetRemoteDescription() function signature.
-class PeerConnectionRtpLegacyObserverTest : public PeerConnectionRtpTest {};
// Sanity test making sure the callback is invoked.
-TEST_F(PeerConnectionRtpLegacyObserverTest, OnSuccess) {
+TEST_P(PeerConnectionRtpTest, LegacyObserverOnSuccess) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
@@ -633,8 +733,8 @@
// Verifies legacy behavior: The observer is not called if if the peer
// connection is destroyed because the asynchronous callback is executed in the
// peer connection's message handler.
-TEST_F(PeerConnectionRtpLegacyObserverTest,
- ObserverNotCalledIfPeerConnectionDereferenced) {
+TEST_P(PeerConnectionRtpTest,
+ LegacyObserverNotCalledIfPeerConnectionDereferenced) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
@@ -651,15 +751,16 @@
// RtpTransceiver Tests.
// Test that by default there are no transceivers with Unified Plan.
-TEST_F(PeerConnectionRtpTest, PeerConnectionHasNoTransceivers) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, PeerConnectionHasNoTransceivers) {
+ auto caller = CreatePeerConnection();
EXPECT_THAT(caller->pc()->GetTransceivers(), ElementsAre());
}
// Test that a transceiver created with the audio kind has the correct initial
// properties.
-TEST_F(PeerConnectionRtpTest, AddTransceiverHasCorrectInitProperties) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ AddTransceiverHasCorrectInitProperties) {
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
EXPECT_EQ(rtc::nullopt, transceiver->mid());
@@ -670,9 +771,9 @@
// Test that adding a transceiver with the audio kind creates an audio sender
// and audio receiver with the receiver having a live audio track.
-TEST_F(PeerConnectionRtpTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddAudioTransceiverCreatesAudioSenderAndReceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->media_type());
@@ -691,9 +792,9 @@
// Test that adding a transceiver with the video kind creates an video sender
// and video receiver with the receiver having a live video track.
-TEST_F(PeerConnectionRtpTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddAudioTransceiverCreatesVideoSenderAndReceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type());
@@ -713,8 +814,8 @@
// Test that after a call to AddTransceiver, the transceiver shows in
// GetTransceivers(), the transceiver's sender shows in GetSenders(), and the
// transceiver's receiver shows in GetReceivers().
-TEST_F(PeerConnectionRtpTest, AddTransceiverShowsInLists) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTransceiverShowsInLists) {
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
EXPECT_EQ(
@@ -732,8 +833,9 @@
// Test that the direction passed in through the AddTransceiver init parameter
// is set in the returned transceiver.
-TEST_F(PeerConnectionRtpTest, AddTransceiverWithDirectionIsReflected) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ AddTransceiverWithDirectionIsReflected) {
+ auto caller = CreatePeerConnection();
RtpTransceiverInit init;
init.direction = RtpTransceiverDirection::kSendOnly;
@@ -743,8 +845,9 @@
// Test that calling AddTransceiver with a track creates a transceiver which has
// its sender's track set to the passed-in track.
-TEST_F(PeerConnectionRtpTest, AddTransceiverWithTrackCreatesSenderWithTrack) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ AddTransceiverWithTrackCreatesSenderWithTrack) {
+ auto caller = CreatePeerConnection();
auto audio_track = caller->CreateAudioTrack("audio track");
auto transceiver = caller->AddTransceiver(audio_track);
@@ -762,9 +865,9 @@
// Test that calling AddTransceiver twice with the same track creates distinct
// transceivers, senders with the same track.
-TEST_F(PeerConnectionRtpTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddTransceiverTwiceWithSameTrackCreatesMultipleTransceivers) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto audio_track = caller->CreateAudioTrack("audio track");
@@ -787,27 +890,27 @@
// RtpTransceiver error handling tests.
-TEST_F(PeerConnectionRtpTest, AddTransceiverWithInvalidKindReturnsError) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ AddTransceiverWithInvalidKindReturnsError) {
+ auto caller = CreatePeerConnection();
auto result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_DATA);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
}
-TEST_F(PeerConnectionRtpTest, UnifiedPlanCanClosePeerConnection) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
+ CanClosePeerConnectionWithoutCrashing) {
+ auto caller = CreatePeerConnection();
caller->pc()->Close();
}
// Unified Plan AddTrack tests.
-class PeerConnectionRtpUnifiedPlanTest : public PeerConnectionRtpTest {};
-
// Test that adding an audio track creates a new audio RtpSender with the given
// track.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddAudioTrackCreatesAudioSender) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddAudioTrackCreatesAudioSender) {
+ auto caller = CreatePeerConnection();
auto audio_track = caller->CreateAudioTrack("a");
auto sender = caller->AddTrack(audio_track);
@@ -819,8 +922,8 @@
// Test that adding a video track creates a new video RtpSender with the given
// track.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddVideoTrackCreatesVideoSender) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddVideoTrackCreatesVideoSender) {
+ auto caller = CreatePeerConnection();
auto video_track = caller->CreateVideoTrack("a");
auto sender = caller->AddTrack(video_track);
@@ -832,8 +935,8 @@
// Test that adding a track to a new PeerConnection creates an RtpTransceiver
// with the sender that AddTrack returns and in the sendrecv direction.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddFirstTrackCreatesTransceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddFirstTrackCreatesTransceiver) {
+ auto caller = CreatePeerConnection();
auto sender = caller->AddAudioTrack("a");
ASSERT_TRUE(sender);
@@ -847,8 +950,8 @@
// Test that if a transceiver of the same type but no track had been added to
// the PeerConnection and later a call to AddTrack is made, the resulting sender
// is the transceiver's sender and the sender's track is the newly-added track.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackReusesTransceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackReusesTransceiver) {
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
auto audio_track = caller->CreateAudioTrack("a");
@@ -864,8 +967,8 @@
// Test that adding two tracks to a new PeerConnection creates two
// RtpTransceivers in the same order.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, TwoAddTrackCreatesTwoTransceivers) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, TwoAddTrackCreatesTwoTransceivers) {
+ auto caller = CreatePeerConnection();
auto sender1 = caller->AddAudioTrack("a");
auto sender2 = caller->AddVideoTrack("v");
@@ -880,8 +983,8 @@
// Test that if there are multiple transceivers with no sending track then a
// later call to AddTrack will use the one of the same type as the newly-added
// track.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackReusesTransceiverOfType) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackReusesTransceiverOfType) {
+ auto caller = CreatePeerConnection();
auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
auto video_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
@@ -895,9 +998,9 @@
// Test that if the only transceivers that do not have a sending track have a
// different type from the added track, then AddTrack will create a new
// transceiver for the track.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddTrackDoesNotReuseTransceiverOfWrongType) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
auto sender = caller->AddVideoTrack("v");
@@ -910,9 +1013,9 @@
// Test that the first available transceiver is reused by AddTrack when multiple
// are available.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddTrackReusesFirstMatchingTransceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
@@ -926,9 +1029,9 @@
// Test that a call to AddTrack that reuses a transceiver will change the
// direction from inactive to sendonly.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddTrackChangesDirectionFromInactiveToSendOnly) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
RtpTransceiverInit init;
init.direction = RtpTransceiverDirection::kInactive;
@@ -943,9 +1046,9 @@
// Test that a call to AddTrack that reuses a transceiver will change the
// direction from recvonly to sendrecv.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
AddTrackChangesDirectionFromRecvOnlyToSendRecv) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
RtpTransceiverInit init;
init.direction = RtpTransceiverDirection::kRecvOnly;
@@ -958,10 +1061,10 @@
EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
}
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackCreatesSenderWithTrackId) {
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackCreatesSenderWithTrackId) {
const std::string kTrackId = "audio_track";
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto audio_track = caller->CreateAudioTrack(kTrackId);
auto sender = caller->AddTrack(audio_track);
@@ -971,8 +1074,8 @@
// Unified Plan AddTrack error handling.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackErrorIfClosed) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackErrorIfClosed) {
+ auto caller = CreatePeerConnection();
auto audio_track = caller->CreateAudioTrack("a");
caller->pc()->Close();
@@ -984,8 +1087,8 @@
EXPECT_FALSE(caller->observer()->negotiation_needed());
}
-TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackErrorIfTrackAlreadyHasSender) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackErrorIfTrackAlreadyHasSender) {
+ auto caller = CreatePeerConnection();
auto audio_track = caller->CreateAudioTrack("a");
ASSERT_TRUE(caller->AddTrack(audio_track));
@@ -1001,8 +1104,8 @@
// Test that calling RemoveTrack on a sender with a previously-added track
// clears the sender's track.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, RemoveTrackClearsSenderTrack) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackClearsSenderTrack) {
+ auto caller = CreatePeerConnection();
auto sender = caller->AddAudioTrack("a");
ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
@@ -1012,9 +1115,9 @@
// Test that calling RemoveTrack on a sender where the transceiver is configured
// in the sendrecv direction changes the transceiver's direction to recvonly.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
RemoveTrackChangesDirectionFromSendRecvToRecvOnly) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
RtpTransceiverInit init;
init.direction = RtpTransceiverDirection::kSendRecv;
@@ -1031,9 +1134,9 @@
// Test that calling RemoveTrack on a sender where the transceiver is configured
// in the sendonly direction changes the transceiver's direction to inactive.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
RemoveTrackChangesDirectionFromSendOnlyToInactive) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
RtpTransceiverInit init;
init.direction = RtpTransceiverDirection::kSendOnly;
@@ -1049,8 +1152,8 @@
// Test that calling RemoveTrack with a sender that has a null track results in
// no change in state.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, RemoveTrackWithNullSenderTrackIsNoOp) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackWithNullSenderTrackIsNoOp) {
+ auto caller = CreatePeerConnection();
auto sender = caller->AddAudioTrack("a");
auto transceiver = caller->pc()->GetTransceivers()[0];
@@ -1065,8 +1168,8 @@
// Unified Plan RemoveTrack error handling.
-TEST_F(PeerConnectionRtpUnifiedPlanTest, RemoveTrackErrorIfClosed) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackErrorIfClosed) {
+ auto caller = CreatePeerConnection();
auto sender = caller->AddAudioTrack("a");
caller->pc()->Close();
@@ -1076,9 +1179,9 @@
EXPECT_FALSE(caller->observer()->negotiation_needed());
}
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
RemoveTrackNoErrorIfTrackAlreadyRemoved) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto sender = caller->AddAudioTrack("a");
ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
@@ -1090,9 +1193,9 @@
// Test that OnRenegotiationNeeded is fired if SetDirection is called on an
// active RtpTransceiver with a new direction.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
RenegotiationNeededAfterTransceiverSetDirection) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
@@ -1103,9 +1206,9 @@
// Test that OnRenegotiationNeeded is not fired if SetDirection is called on an
// active RtpTransceiver with current direction.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
NoRenegotiationNeededAfterTransceiverSetSameDirection) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
@@ -1116,9 +1219,9 @@
// Test that OnRenegotiationNeeded is not fired if SetDirection is called on a
// stopped RtpTransceiver.
-TEST_F(PeerConnectionRtpUnifiedPlanTest,
+TEST_F(PeerConnectionRtpTestUnifiedPlan,
NoRenegotiationNeededAfterSetDirectionOnStoppedTransceiver) {
- auto caller = CreatePeerConnectionWithUnifiedPlan();
+ auto caller = CreatePeerConnection();
auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
transceiver->Stop();
@@ -1135,7 +1238,8 @@
// ssrc based MSID signaling. Thus we test here that Unified Plan offers both
// types but answers with the same type as the offer.
-class PeerConnectionMsidSignalingTest : public PeerConnectionRtpTest {};
+class PeerConnectionMsidSignalingTest
+ : public PeerConnectionRtpTestUnifiedPlan {};
TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanTalkingToOurself) {
auto caller = CreatePeerConnectionWithUnifiedPlan();
@@ -1236,7 +1340,7 @@
// Test that the correct UMA metrics are reported for simple/complex SDP.
-class SdpFormatReceivedTest : public PeerConnectionRtpTest {};
+class SdpFormatReceivedTest : public PeerConnectionRtpTestUnifiedPlan {};
#ifdef HAVE_SCTP
TEST_F(SdpFormatReceivedTest, DataChannelOnlyIsReportedAsNoTracks) {
@@ -1309,9 +1413,7 @@
// Sender setups in a call.
-class PeerConnectionSenderTest : public PeerConnectionRtpTest {};
-
-TEST_F(PeerConnectionSenderTest, CreateTwoSendersWithSameTrack) {
+TEST_P(PeerConnectionRtpTest, CreateTwoSendersWithSameTrack) {
auto caller = CreatePeerConnection();
auto callee = CreatePeerConnection();
@@ -1325,9 +1427,18 @@
EXPECT_TRUE(sender2);
EXPECT_TRUE(sender1->SetTrack(track));
- // TODO(hbos): When https://crbug.com/webrtc/8734 is resolved, this should
- // return true, and doing |callee->SetRemoteDescription()| should work.
- EXPECT_FALSE(caller->CreateOfferAndSetAsLocal());
+ if (sdp_semantics_ == SdpSemantics::kPlanB) {
+ // TODO(hbos): When https://crbug.com/webrtc/8734 is resolved, this should
+ // return true, and doing |callee->SetRemoteDescription()| should work.
+ EXPECT_FALSE(caller->CreateOfferAndSetAsLocal());
+ } else {
+ EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
+ }
}
+INSTANTIATE_TEST_CASE_P(PeerConnectionRtpTest,
+ PeerConnectionRtpTest,
+ Values(SdpSemantics::kPlanB,
+ SdpSemantics::kUnifiedPlan));
+
} // namespace webrtc