Index: talk/app/webrtc/peerconnectioninterface_unittest.cc |
diff --git a/talk/app/webrtc/peerconnectioninterface_unittest.cc b/talk/app/webrtc/peerconnectioninterface_unittest.cc |
index 5e88658a4e25ce3c464853dfbba53a1335829c63..2cbb8b2eee8718993020e70888fb575c4f180481 100644 |
--- a/talk/app/webrtc/peerconnectioninterface_unittest.cc |
+++ b/talk/app/webrtc/peerconnectioninterface_unittest.cc |
@@ -244,6 +244,7 @@ using webrtc::DataChannelInterface; |
using webrtc::FakeConstraints; |
using webrtc::FakePortAllocatorFactory; |
using webrtc::IceCandidateInterface; |
+using webrtc::MediaConstraintsInterface; |
using webrtc::MediaStream; |
using webrtc::MediaStreamInterface; |
using webrtc::MediaStreamTrackInterface; |
@@ -642,26 +643,30 @@ class PeerConnectionInterfaceTest : public testing::Test { |
observer_.renegotiation_needed_ = false; |
} |
- bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, bool offer) { |
+ bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, |
+ bool offer, |
+ MediaConstraintsInterface* constraints) { |
rtc::scoped_refptr<MockCreateSessionDescriptionObserver> |
observer(new rtc::RefCountedObject< |
MockCreateSessionDescriptionObserver>()); |
if (offer) { |
- pc_->CreateOffer(observer, NULL); |
+ pc_->CreateOffer(observer, constraints); |
} else { |
- pc_->CreateAnswer(observer, NULL); |
+ pc_->CreateAnswer(observer, constraints); |
} |
EXPECT_EQ_WAIT(true, observer->called(), kTimeout); |
*desc = observer->release_desc(); |
return observer->result(); |
} |
- bool DoCreateOffer(SessionDescriptionInterface** desc) { |
- return DoCreateOfferAnswer(desc, true); |
+ bool DoCreateOffer(SessionDescriptionInterface** desc, |
+ MediaConstraintsInterface* constraints) { |
+ return DoCreateOfferAnswer(desc, true, constraints); |
} |
- bool DoCreateAnswer(SessionDescriptionInterface** desc) { |
- return DoCreateOfferAnswer(desc, false); |
+ bool DoCreateAnswer(SessionDescriptionInterface** desc, |
+ MediaConstraintsInterface* constraints) { |
+ return DoCreateOfferAnswer(desc, false, constraints); |
} |
bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) { |
@@ -721,7 +726,7 @@ class PeerConnectionInterfaceTest : public testing::Test { |
void CreateOfferAsRemoteDescription() { |
rtc::scoped_ptr<SessionDescriptionInterface> offer; |
- ASSERT_TRUE(DoCreateOffer(offer.use())); |
+ ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); |
std::string sdp; |
EXPECT_TRUE(offer->ToString(&sdp)); |
SessionDescriptionInterface* remote_offer = |
@@ -741,7 +746,7 @@ class PeerConnectionInterfaceTest : public testing::Test { |
void CreateAnswerAsLocalDescription() { |
scoped_ptr<SessionDescriptionInterface> answer; |
- ASSERT_TRUE(DoCreateAnswer(answer.use())); |
+ ASSERT_TRUE(DoCreateAnswer(answer.use(), nullptr)); |
// TODO(perkj): Currently SetLocalDescription fails if any parameters in an |
// audio codec change, even if the parameter has nothing to do with |
@@ -761,7 +766,7 @@ class PeerConnectionInterfaceTest : public testing::Test { |
void CreatePrAnswerAsLocalDescription() { |
scoped_ptr<SessionDescriptionInterface> answer; |
- ASSERT_TRUE(DoCreateAnswer(answer.use())); |
+ ASSERT_TRUE(DoCreateAnswer(answer.use(), nullptr)); |
std::string sdp; |
EXPECT_TRUE(answer->ToString(&sdp)); |
@@ -781,7 +786,7 @@ class PeerConnectionInterfaceTest : public testing::Test { |
void CreateOfferAsLocalDescription() { |
rtc::scoped_ptr<SessionDescriptionInterface> offer; |
- ASSERT_TRUE(DoCreateOffer(offer.use())); |
+ ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); |
// TODO(perkj): Currently SetLocalDescription fails if any parameters in an |
// audio codec change, even if the parameter has nothing to do with |
// receiving. Not all parameters are serialized to SDP. |
@@ -951,7 +956,7 @@ TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) { |
CreatePeerConnection(); |
AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track"); |
scoped_ptr<SessionDescriptionInterface> offer; |
- ASSERT_TRUE(DoCreateOffer(offer.accept())); |
+ ASSERT_TRUE(DoCreateOffer(offer.accept(), nullptr)); |
const cricket::ContentInfo* audio_content = |
cricket::GetFirstAudioContent(offer->description()); |
@@ -972,7 +977,7 @@ TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) { |
// Add another stream and ensure the offer includes both the old and new |
// streams. |
AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2"); |
- ASSERT_TRUE(DoCreateOffer(offer.accept())); |
+ ASSERT_TRUE(DoCreateOffer(offer.accept(), nullptr)); |
audio_content = cricket::GetFirstAudioContent(offer->description()); |
audio_desc = static_cast<const cricket::AudioContentDescription*>( |
@@ -1068,12 +1073,12 @@ TEST_F(PeerConnectionInterfaceTest, IceCandidates) { |
// SetRemoteDescription takes ownership of offer. |
SessionDescriptionInterface* offer = NULL; |
AddVideoStream(kStreamLabel1); |
- EXPECT_TRUE(DoCreateOffer(&offer)); |
+ EXPECT_TRUE(DoCreateOffer(&offer, nullptr)); |
EXPECT_TRUE(DoSetRemoteDescription(offer)); |
// SetLocalDescription takes ownership of answer. |
SessionDescriptionInterface* answer = NULL; |
- EXPECT_TRUE(DoCreateAnswer(&answer)); |
+ EXPECT_TRUE(DoCreateAnswer(&answer, nullptr)); |
EXPECT_TRUE(DoSetLocalDescription(answer)); |
EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout); |
@@ -1088,7 +1093,7 @@ TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { |
CreatePeerConnection(); |
// Create a regular offer for the CreateAnswer test later. |
SessionDescriptionInterface* offer = NULL; |
- EXPECT_TRUE(DoCreateOffer(&offer)); |
+ EXPECT_TRUE(DoCreateOffer(&offer, nullptr)); |
EXPECT_TRUE(offer != NULL); |
delete offer; |
offer = NULL; |
@@ -1097,11 +1102,11 @@ TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { |
AddAudioVideoStream(kStreamLabel1, "track_label", "track_label"); |
// Test CreateOffer |
- EXPECT_FALSE(DoCreateOffer(&offer)); |
+ EXPECT_FALSE(DoCreateOffer(&offer, nullptr)); |
// Test CreateAnswer |
SessionDescriptionInterface* answer = NULL; |
- EXPECT_FALSE(DoCreateAnswer(&answer)); |
+ EXPECT_FALSE(DoCreateAnswer(&answer, nullptr)); |
} |
// Test that we will get different SSRCs for each tracks in the offer and answer |
@@ -1113,7 +1118,7 @@ TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) { |
// Test CreateOffer |
scoped_ptr<SessionDescriptionInterface> offer; |
- ASSERT_TRUE(DoCreateOffer(offer.use())); |
+ ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); |
int audio_ssrc = 0; |
int video_ssrc = 0; |
EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()), |
@@ -1125,7 +1130,7 @@ TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) { |
// Test CreateAnswer |
EXPECT_TRUE(DoSetRemoteDescription(offer.release())); |
scoped_ptr<SessionDescriptionInterface> answer; |
- ASSERT_TRUE(DoCreateAnswer(answer.use())); |
+ ASSERT_TRUE(DoCreateAnswer(answer.use(), nullptr)); |
audio_ssrc = 0; |
video_ssrc = 0; |
EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()), |
@@ -1572,6 +1577,73 @@ TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) { |
CreateAnswerAsLocalDescription(); |
} |
+// Test that if we're receiving (but not sending) a track, subsequent offers |
+// will have m-lines with a=recvonly. |
+TEST_F(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) { |
+ FakeConstraints constraints; |
+ constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
+ true); |
+ CreatePeerConnection(&constraints); |
+ CreateAndSetRemoteOffer(kSdpStringWithStream1); |
+ CreateAnswerAsLocalDescription(); |
+ |
+ // At this point we should be receiving stream 1, but not sending anything. |
+ // A new offer should be recvonly. |
+ SessionDescriptionInterface* offer; |
+ DoCreateOffer(&offer, nullptr); |
+ |
+ const cricket::ContentInfo* video_content = |
+ cricket::GetFirstVideoContent(offer->description()); |
+ const cricket::VideoContentDescription* video_desc = |
+ static_cast<const cricket::VideoContentDescription*>( |
+ video_content->description); |
+ ASSERT_EQ(cricket::MD_RECVONLY, video_desc->direction()); |
+ |
+ const cricket::ContentInfo* audio_content = |
+ cricket::GetFirstAudioContent(offer->description()); |
+ const cricket::AudioContentDescription* audio_desc = |
+ static_cast<const cricket::AudioContentDescription*>( |
+ audio_content->description); |
+ ASSERT_EQ(cricket::MD_RECVONLY, audio_desc->direction()); |
+} |
+ |
+// Test that if we're receiving (but not sending) a track, and the |
+// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to |
+// false, the generated m-lines will be a=inactive. |
+TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) { |
+ FakeConstraints constraints; |
+ constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
+ true); |
+ CreatePeerConnection(&constraints); |
+ CreateAndSetRemoteOffer(kSdpStringWithStream1); |
+ CreateAnswerAsLocalDescription(); |
+ |
+ // At this point we should be receiving stream 1, but not sending anything. |
+ // A new offer would be recvonly, but we'll set the "no receive" constraints |
+ // to make it inactive. |
+ SessionDescriptionInterface* offer; |
+ FakeConstraints offer_constraints; |
+ offer_constraints.AddMandatory( |
+ webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, false); |
+ offer_constraints.AddMandatory( |
+ webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, false); |
+ DoCreateOffer(&offer, &offer_constraints); |
+ |
+ const cricket::ContentInfo* video_content = |
+ cricket::GetFirstVideoContent(offer->description()); |
+ const cricket::VideoContentDescription* video_desc = |
+ static_cast<const cricket::VideoContentDescription*>( |
+ video_content->description); |
+ ASSERT_EQ(cricket::MD_INACTIVE, video_desc->direction()); |
+ |
+ const cricket::ContentInfo* audio_content = |
+ cricket::GetFirstAudioContent(offer->description()); |
+ const cricket::AudioContentDescription* audio_desc = |
+ static_cast<const cricket::AudioContentDescription*>( |
+ audio_content->description); |
+ ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction()); |
+} |
+ |
// Test that PeerConnection::Close changes the states to closed and all remote |
// tracks change state to ended. |
TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) { |
@@ -1628,9 +1700,9 @@ TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) { |
EXPECT_TRUE(pc_->remote_description() != NULL); |
rtc::scoped_ptr<SessionDescriptionInterface> offer; |
- EXPECT_TRUE(DoCreateOffer(offer.use())); |
+ EXPECT_TRUE(DoCreateOffer(offer.use(), nullptr)); |
rtc::scoped_ptr<SessionDescriptionInterface> answer; |
- EXPECT_TRUE(DoCreateAnswer(answer.use())); |
+ EXPECT_TRUE(DoCreateAnswer(answer.use(), nullptr)); |
std::string sdp; |
ASSERT_TRUE(pc_->remote_description()->ToString(&sdp)); |
@@ -1734,7 +1806,7 @@ TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) { |
EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state()); |
rtc::scoped_ptr<SessionDescriptionInterface> local_answer; |
- EXPECT_TRUE(DoCreateAnswer(local_answer.accept())); |
+ EXPECT_TRUE(DoCreateAnswer(local_answer.accept(), nullptr)); |
cricket::ContentInfo* video_info = |
local_answer->description()->GetContentByName("video"); |
video_info->rejected = true; |
@@ -1744,7 +1816,7 @@ TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) { |
// Now create an offer where we reject both video and audio. |
rtc::scoped_ptr<SessionDescriptionInterface> local_offer; |
- EXPECT_TRUE(DoCreateOffer(local_offer.accept())); |
+ EXPECT_TRUE(DoCreateOffer(local_offer.accept(), nullptr)); |
video_info = local_offer->description()->GetContentByName("video"); |
ASSERT_TRUE(video_info != nullptr); |
video_info->rejected = true; |
@@ -1900,7 +1972,7 @@ TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) { |
// Create an offer just to ensure we have an identity before we manually |
// call SetLocalDescription. |
rtc::scoped_ptr<SessionDescriptionInterface> throwaway; |
- ASSERT_TRUE(DoCreateOffer(throwaway.accept())); |
+ ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); |
rtc::scoped_ptr<SessionDescriptionInterface> desc_1; |
CreateSessionDescriptionAndReference(2, 2, desc_1.accept()); |
@@ -1937,7 +2009,7 @@ TEST_F(PeerConnectionInterfaceTest, |
// Create an offer just to ensure we have an identity before we manually |
// call SetLocalDescription. |
rtc::scoped_ptr<SessionDescriptionInterface> throwaway; |
- ASSERT_TRUE(DoCreateOffer(throwaway.accept())); |
+ ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); |
rtc::scoped_ptr<SessionDescriptionInterface> desc_1; |
CreateSessionDescriptionAndReference(2, 2, desc_1.accept()); |
@@ -1966,7 +2038,7 @@ TEST_F(PeerConnectionInterfaceTest, |
// Create an offer just to ensure we have an identity before we manually |
// call SetLocalDescription. |
rtc::scoped_ptr<SessionDescriptionInterface> throwaway; |
- ASSERT_TRUE(DoCreateOffer(throwaway.accept())); |
+ ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); |
rtc::scoped_ptr<SessionDescriptionInterface> desc; |
CreateSessionDescriptionAndReference(1, 1, desc.accept()); |
@@ -2012,7 +2084,7 @@ TEST_F(PeerConnectionInterfaceTest, SignalSameTracksInSeparateMediaStream) { |
// Create an offer just to ensure we have an identity before we manually |
// call SetLocalDescription. |
rtc::scoped_ptr<SessionDescriptionInterface> throwaway; |
- ASSERT_TRUE(DoCreateOffer(throwaway.accept())); |
+ ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); |
rtc::scoped_ptr<SessionDescriptionInterface> desc; |
CreateSessionDescriptionAndReference(1, 1, desc.accept()); |
@@ -2049,6 +2121,9 @@ TEST_F(PeerConnectionInterfaceTest, SignalSameTracksInSeparateMediaStream) { |
} |
// The following tests verify that session options are created correctly. |
+// TODO(deadbeef): Convert these tests to be more end-to-end. Instead of |
+// "verify options are converted correctly", should be "pass options into |
+// CreateOffer and verify the correct offer is produced." |
TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) { |
RTCOfferAnswerOptions rtc_options; |
@@ -2075,8 +2150,7 @@ TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) { |
} |
// Test that a MediaSessionOptions is created for an offer if |
-// OfferToReceiveAudio and OfferToReceiveVideo options are set but no |
-// MediaStreams are sent. |
+// OfferToReceiveAudio and OfferToReceiveVideo options are set. |
TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) { |
RTCOfferAnswerOptions rtc_options; |
rtc_options.offer_to_receive_audio = 1; |
@@ -2090,7 +2164,7 @@ TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) { |
} |
// Test that a correct MediaSessionOptions is created for an offer if |
-// OfferToReceiveAudio is set but no MediaStreams are sent. |
+// OfferToReceiveAudio is set. |
TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) { |
RTCOfferAnswerOptions rtc_options; |
rtc_options.offer_to_receive_audio = 1; |
@@ -2103,21 +2177,21 @@ TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) { |
} |
// Test that a correct MediaSessionOptions is created for an offer if |
-// the default OfferOptons is used or MediaStreams are sent. |
+// the default OfferOptions are used. |
TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) { |
RTCOfferAnswerOptions rtc_options; |
cricket::MediaSessionOptions options; |
EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); |
- EXPECT_FALSE(options.has_audio()); |
+ EXPECT_TRUE(options.has_audio()); |
EXPECT_FALSE(options.has_video()); |
- EXPECT_FALSE(options.bundle_enabled); |
+ EXPECT_TRUE(options.bundle_enabled); |
EXPECT_TRUE(options.vad_enabled); |
EXPECT_FALSE(options.transport_options.ice_restart); |
} |
// Test that a correct MediaSessionOptions is created for an offer if |
-// OfferToReceiveVideo is set but no MediaStreams are sent. |
+// OfferToReceiveVideo is set. |
TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) { |
RTCOfferAnswerOptions rtc_options; |
rtc_options.offer_to_receive_audio = 0; |
@@ -2176,19 +2250,19 @@ TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) { |
EXPECT_TRUE(answer_options.has_audio()); |
EXPECT_TRUE(answer_options.has_video()); |
- RTCOfferAnswerOptions rtc_offer_optoins; |
+ RTCOfferAnswerOptions rtc_offer_options; |
cricket::MediaSessionOptions offer_options; |
- EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_offer_optoins, &offer_options)); |
- EXPECT_FALSE(offer_options.has_audio()); |
+ EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_offer_options, &offer_options)); |
+ EXPECT_TRUE(offer_options.has_audio()); |
EXPECT_FALSE(offer_options.has_video()); |
- RTCOfferAnswerOptions updated_rtc_offer_optoins; |
- updated_rtc_offer_optoins.offer_to_receive_audio = 1; |
- updated_rtc_offer_optoins.offer_to_receive_video = 1; |
+ RTCOfferAnswerOptions updated_rtc_offer_options; |
+ updated_rtc_offer_options.offer_to_receive_audio = 1; |
+ updated_rtc_offer_options.offer_to_receive_video = 1; |
cricket::MediaSessionOptions updated_offer_options; |
- EXPECT_TRUE(ConvertRtcOptionsForOffer(updated_rtc_offer_optoins, |
+ EXPECT_TRUE(ConvertRtcOptionsForOffer(updated_rtc_offer_options, |
&updated_offer_options)); |
EXPECT_TRUE(updated_offer_options.has_audio()); |
EXPECT_TRUE(updated_offer_options.has_video()); |
@@ -2207,12 +2281,4 @@ TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) { |
ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options)); |
EXPECT_TRUE(updated_answer_options.has_audio()); |
EXPECT_TRUE(updated_answer_options.has_video()); |
- |
- RTCOfferAnswerOptions default_rtc_options; |
- EXPECT_TRUE( |
- ConvertRtcOptionsForOffer(default_rtc_options, &updated_offer_options)); |
- // By default, |has_audio| or |has_video| are false if there is no media |
- // track. |
- EXPECT_FALSE(updated_offer_options.has_audio()); |
- EXPECT_FALSE(updated_offer_options.has_video()); |
} |