 Chromium Code Reviews
 Chromium Code Reviews Issue 2991693002:
  Adding support for Unified Plan offer/answer negotiation.  (Closed)
    
  
    Issue 2991693002:
  Adding support for Unified Plan offer/answer negotiation.  (Closed) 
  | Index: webrtc/pc/mediasession_unittest.cc | 
| diff --git a/webrtc/pc/mediasession_unittest.cc b/webrtc/pc/mediasession_unittest.cc | 
| index ae8d13940b6f91bbf9f3636cb12be75ec1db1b9d..fff76d0ee7fb9a630cb4462baf06997b7606bd5d 100644 | 
| --- a/webrtc/pc/mediasession_unittest.cc | 
| +++ b/webrtc/pc/mediasession_unittest.cc | 
| @@ -34,6 +34,7 @@ typedef std::vector<cricket::Candidate> Candidates; | 
| using cricket::MediaContentDescription; | 
| using cricket::MediaSessionDescriptionFactory; | 
| using cricket::MediaContentDirection; | 
| +using cricket::MediaDescriptionOptions; | 
| using cricket::MediaSessionOptions; | 
| using cricket::MediaType; | 
| using cricket::SessionDescription; | 
| @@ -237,6 +238,65 @@ static std::vector<std::string> GetCodecNames(const std::vector<T>& codecs) { | 
| return codec_names; | 
| } | 
| +// Add a media section to the |session_options|. | 
| +static void AddMediaSection(MediaType type, | 
| + const std::string& mid, | 
| + bool send, | 
| + bool recv, | 
| + bool stopped, | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
nit: I'd replace "send/recv" with a MediaContentDi
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| + MediaSessionOptions& session_options) { | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
nit: Since this an out parameter it should be pass
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| + session_options.media_description_options.push_back(MediaDescriptionOptions( | 
| + type, mid, cricket::RtpTransceiverDirection(send, recv), stopped)); | 
| +} | 
| + | 
| +static void AttachSenderToMediaSection(const std::string& mid, | 
| + MediaType type, | 
| + const std::string& track_id, | 
| + const std::string& stream_id, | 
| + int num_sim_layer, | 
| + MediaSessionOptions& session_options) { | 
| + auto it = session_options.FindMediaDescription(mid); | 
| + switch (type) { | 
| + case MEDIA_TYPE_AUDIO: | 
| + it->AddAudioSender(track_id, stream_id); | 
| + break; | 
| + case MEDIA_TYPE_VIDEO: | 
| + it->AddVideoSender(track_id, stream_id, num_sim_layer); | 
| + break; | 
| + case MEDIA_TYPE_DATA: | 
| + it->AddRtpDataChannel(track_id, stream_id); | 
| + break; | 
| + default: | 
| + RTC_NOTREACHED(); | 
| + } | 
| +} | 
| + | 
| +static void DetachSenderFromMediaSection(const std::string& mid, | 
| + const std::string& track_id, | 
| + MediaSessionOptions& session_options) { | 
| + auto it = session_options.FindMediaDescription(mid); | 
| + auto sender_it = it->sender_options.begin(); | 
| + for (; sender_it != it->sender_options.end(); ++sender_it) { | 
| + if (sender_it->track_id == track_id) { | 
| + it->sender_options.erase(sender_it); | 
| + return; | 
| + } | 
| + } | 
| + RTC_NOTREACHED(); | 
| +} | 
| + | 
| +// Helper function used to create a default MediaSessionOptions for Plan B SDP. | 
| +// (https://tools.ietf.org/html/draft-uberti-rtcweb-plan-00). | 
| +static MediaSessionOptions CreatePlanBMediaSessionOptions() { | 
| + MediaSessionOptions session_options; | 
| + bool send = false; | 
| + bool recv = true; | 
| + bool stopped = false; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", send, recv, stopped, | 
| + session_options); | 
| + return session_options; | 
| +} | 
| + | 
| class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| public: | 
| MediaSessionDescriptionFactoryTest() | 
| @@ -305,7 +365,8 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| return iter != ice_options.end(); | 
| } | 
| - void TestTransportInfo(bool offer, const MediaSessionOptions& options, | 
| + void TestTransportInfo(bool offer, | 
| + MediaSessionOptions& options, | 
| bool has_current_desc) { | 
| const std::string current_audio_ufrag = "current_audio_ufrag"; | 
| const std::string current_audio_pwd = "current_audio_pwd"; | 
| @@ -350,7 +411,10 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| EXPECT_EQ(static_cast<size_t>(cricket::ICE_PWD_LENGTH), | 
| ti_audio->description.ice_pwd.size()); | 
| } | 
| - EXPECT_EQ(options.enable_ice_renomination, GetIceRenomination(ti_audio)); | 
| + auto media_desc_options_it = options.FindMediaDescription("audio"); | 
| + EXPECT_EQ( | 
| + media_desc_options_it->transport_options.enable_ice_renomination, | 
| + GetIceRenomination(ti_audio)); | 
| } else { | 
| EXPECT_TRUE(ti_audio == NULL); | 
| @@ -374,7 +438,10 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| ti_video->description.ice_pwd.size()); | 
| } | 
| } | 
| - EXPECT_EQ(options.enable_ice_renomination, GetIceRenomination(ti_video)); | 
| + auto media_desc_options_it = options.FindMediaDescription("video"); | 
| + EXPECT_EQ( | 
| + media_desc_options_it->transport_options.enable_ice_renomination, | 
| + GetIceRenomination(ti_video)); | 
| } else { | 
| EXPECT_TRUE(ti_video == NULL); | 
| } | 
| @@ -397,7 +464,10 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| ti_data->description.ice_pwd.size()); | 
| } | 
| } | 
| - EXPECT_EQ(options.enable_ice_renomination, GetIceRenomination(ti_data)); | 
| + auto media_desc_options_it = options.FindMediaDescription("data"); | 
| + EXPECT_EQ( | 
| + media_desc_options_it->transport_options.enable_ice_renomination, | 
| + GetIceRenomination(ti_data)); | 
| } else { | 
| EXPECT_TRUE(ti_video == NULL); | 
| @@ -407,9 +477,13 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| void TestCryptoWithBundle(bool offer) { | 
| f1_.set_secure(SEC_ENABLED); | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| std::unique_ptr<SessionDescription> ref_desc; | 
| std::unique_ptr<SessionDescription> desc; | 
| if (offer) { | 
| @@ -459,23 +533,32 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| void TestMediaDirectionInAnswer( | 
| cricket::MediaContentDirection direction_in_offer, | 
| cricket::MediaContentDirection expected_direction_in_answer) { | 
| - MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| + MediaSessionOptions offer_opts; | 
| + bool offer_send = (direction_in_offer == cricket::MD_SENDRECV || | 
| + direction_in_offer == cricket::MD_SENDONLY); | 
| + bool offer_recv = (direction_in_offer == cricket::MD_SENDRECV || | 
| + direction_in_offer == cricket::MD_RECVONLY); | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
If "send/recv" were replaced with a MediaContentDi
 
Zhi Huang
2017/08/02 04:38:35
Yes, thanks for the suggestion.
 | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", offer_send, offer_recv, | 
| + false /*stopped*/, offer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", offer_send, offer_recv, | 
| + false /*stopped*/, offer_opts); | 
| + | 
| + MediaSessionOptions answer_opts; | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
nit: I'd put the answer opts above CreateAnswer.
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + | 
| + std::unique_ptr<SessionDescription> offer( | 
| + f1_.CreateOffer(offer_opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| ContentInfo* ac_offer = offer->GetContentByName("audio"); | 
| ASSERT_TRUE(ac_offer != NULL); | 
| - AudioContentDescription* acd_offer = | 
| - static_cast<AudioContentDescription*>(ac_offer->description); | 
| - acd_offer->set_direction(direction_in_offer); | 
| ContentInfo* vc_offer = offer->GetContentByName("video"); | 
| ASSERT_TRUE(vc_offer != NULL); | 
| - VideoContentDescription* vcd_offer = | 
| - static_cast<VideoContentDescription*>(vc_offer->description); | 
| - vcd_offer->set_direction(direction_in_offer); | 
| std::unique_ptr<SessionDescription> answer( | 
| - f2_.CreateAnswer(offer.get(), opts, NULL)); | 
| + f2_.CreateAnswer(offer.get(), answer_opts, NULL)); | 
| const AudioContentDescription* acd_answer = | 
| GetFirstAudioContentDescription(answer.get()); | 
| EXPECT_EQ(expected_direction_in_answer, acd_answer->direction()); | 
| @@ -499,10 +582,16 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| void TestVideoGcmCipher(bool gcm_offer, bool gcm_answer) { | 
| MediaSessionOptions offer_opts; | 
| - offer_opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| offer_opts.crypto_options.enable_gcm_crypto_suites = gcm_offer; | 
| MediaSessionOptions answer_opts; | 
| - answer_opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| answer_opts.crypto_options.enable_gcm_crypto_suites = gcm_answer; | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| @@ -524,7 +613,7 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 
| if (gcm_offer && gcm_answer) { | 
| ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); | 
| @@ -533,7 +622,7 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| } | 
| EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); | 
| - EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux | 
| if (gcm_offer && gcm_answer) { | 
| ASSERT_CRYPTO(vcd, 1U, CS_AEAD_AES_256_GCM); | 
| @@ -554,7 +643,7 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer( | 
| - f1_.CreateOffer(MediaSessionOptions(), NULL)); | 
| + f1_.CreateOffer(CreatePlanBMediaSessionOptions(), NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| const ContentInfo* ac = offer->GetContentByName("audio"); | 
| const ContentInfo* vc = offer->GetContentByName("video"); | 
| @@ -565,7 +654,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { | 
| static_cast<const AudioContentDescription*>(ac->description); | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached. | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) | 
| EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on | 
| ASSERT_CRYPTO(acd, 2U, CS_AES_CM_128_HMAC_SHA1_32); | 
| @@ -575,7 +664,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { | 
| // Create a typical video offer, and ensure it matches what we expect. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| @@ -591,14 +683,14 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { | 
| static_cast<const VideoContentDescription*>(vc->description); | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) | 
| EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on | 
| ASSERT_CRYPTO(acd, 2U, CS_AES_CM_128_HMAC_SHA1_32); | 
| EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); | 
| EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); | 
| EXPECT_EQ(f1_.video_codecs(), vcd->codecs()); | 
| - EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached | 
| EXPECT_EQ(kAutoBandwidth, vcd->bandwidth()); // default bandwidth (auto) | 
| EXPECT_TRUE(vcd->rtcp_mux()); // rtcp-mux defaults on | 
| ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 
| @@ -616,9 +708,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestBundleOfferWithSameCodecPlType) { | 
| ASSERT_EQ(offered_video_codec.id, offered_data_codec.id); | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
A helper method for adding an audio and video sect
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
Setting opts.data_channel_type to DCT_RTP and addi
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| opts.bundle_enabled = true; | 
| std::unique_ptr<SessionDescription> offer(f2_.CreateOffer(opts, NULL)); | 
| const VideoContentDescription* vcd = | 
| @@ -645,8 +741,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = false; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, false /*recv*/, | 
| + true /*stopped*/, opts); | 
| opts.data_channel_type = cricket::DCT_NONE; | 
| opts.bundle_enabled = true; | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| @@ -654,9 +752,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| f2_.CreateAnswer(offer.get(), opts, NULL)); | 
| MediaSessionOptions updated_opts; | 
| - updated_opts.recv_audio = true; | 
| - updated_opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, updated_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, updated_opts); | 
| updated_opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, updated_opts); | 
| updated_opts.bundle_enabled = true; | 
| std::unique_ptr<SessionDescription> updated_offer( | 
| f1_.CreateOffer(updated_opts, answer.get())); | 
| @@ -682,7 +784,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // Create a RTP data offer, and ensure it matches what we expect. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateRtpDataOffer) { | 
| MediaSessionOptions opts; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| @@ -698,14 +806,14 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateRtpDataOffer) { | 
| static_cast<const DataContentDescription*>(dc->description); | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attched. | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) | 
| EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on | 
| ASSERT_CRYPTO(acd, 2U, CS_AES_CM_128_HMAC_SHA1_32); | 
| EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); | 
| EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type()); | 
| EXPECT_EQ(f1_.data_codecs(), dcd->codecs()); | 
| - EXPECT_NE(0U, dcd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, dcd->first_ssrc()); // no sender is attached. | 
| EXPECT_EQ(cricket::kDataMaxBandwidth, | 
| dcd->bandwidth()); // default bandwidth (auto) | 
| EXPECT_TRUE(dcd->rtcp_mux()); // rtcp-mux defaults on | 
| @@ -716,9 +824,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateRtpDataOffer) { | 
| // Create an SCTP data offer with bundle without error. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSctpDataOffer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = false; | 
| opts.bundle_enabled = true; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| EXPECT_TRUE(offer.get() != NULL); | 
| @@ -728,9 +837,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSctpDataOffer) { | 
| // Test creating an sctp data channel from an already generated offer. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateImplicitSctpDataOffer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = false; | 
| opts.bundle_enabled = true; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer1.get() != NULL); | 
| @@ -756,8 +866,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateImplicitSctpDataOffer) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestCreateOfferWithoutLegacyStreams) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - f1_.set_add_legacy_streams(false); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| const ContentInfo* ac = offer->GetContentByName("audio"); | 
| @@ -776,10 +888,14 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // Creates an audio+video sendonly offer. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSendOnlyOffer) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = false; | 
| - options.recv_video = false; | 
| - options.AddSendStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1); | 
| - options.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, false /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, false /*recv*/, | 
| + false /*stopped*/, options); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, kVideoTrack1, | 
| + kMediaStream1, 1, options); | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack1, | 
| + kMediaStream1, 1, options); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(options, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| @@ -795,16 +911,17 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSendOnlyOffer) { | 
| // SessionDescription is preserved in the new SessionDescription. | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
These tests for ordering are a bit obsolete now th
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateOfferContentOrder) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = false; | 
| - opts.recv_video = false; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer1.get() != NULL); | 
| EXPECT_EQ(1u, offer1->contents().size()); | 
| EXPECT_TRUE(IsMediaContentOfType(&offer1->contents()[0], MEDIA_TYPE_DATA)); | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer2( | 
| f1_.CreateOffer(opts, offer1.get())); | 
| ASSERT_TRUE(offer2.get() != NULL); | 
| @@ -812,7 +929,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateOfferContentOrder) { | 
| EXPECT_TRUE(IsMediaContentOfType(&offer2->contents()[0], MEDIA_TYPE_DATA)); | 
| EXPECT_TRUE(IsMediaContentOfType(&offer2->contents()[1], MEDIA_TYPE_VIDEO)); | 
| - opts.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer3( | 
| f1_.CreateOffer(opts, offer2.get())); | 
| ASSERT_TRUE(offer3.get() != NULL); | 
| @@ -820,15 +938,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateOfferContentOrder) { | 
| EXPECT_TRUE(IsMediaContentOfType(&offer3->contents()[0], MEDIA_TYPE_DATA)); | 
| EXPECT_TRUE(IsMediaContentOfType(&offer3->contents()[1], MEDIA_TYPE_VIDEO)); | 
| EXPECT_TRUE(IsMediaContentOfType(&offer3->contents()[2], MEDIA_TYPE_AUDIO)); | 
| - | 
| - // Verifies the default order is audio-video-data, so that the previous checks | 
| - // didn't pass by accident. | 
| - std::unique_ptr<SessionDescription> offer4(f1_.CreateOffer(opts, NULL)); | 
| - ASSERT_TRUE(offer4.get() != NULL); | 
| - EXPECT_EQ(3u, offer4->contents().size()); | 
| - EXPECT_TRUE(IsMediaContentOfType(&offer4->contents()[0], MEDIA_TYPE_AUDIO)); | 
| - EXPECT_TRUE(IsMediaContentOfType(&offer4->contents()[1], MEDIA_TYPE_VIDEO)); | 
| - EXPECT_TRUE(IsMediaContentOfType(&offer4->contents()[2], MEDIA_TYPE_DATA)); | 
| } | 
| // Create a typical audio answer, and ensure it matches what we expect. | 
| @@ -836,10 +945,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) { | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer( | 
| - f1_.CreateOffer(MediaSessionOptions(), NULL)); | 
| + f1_.CreateOffer(CreatePlanBMediaSessionOptions(), NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| std::unique_ptr<SessionDescription> answer( | 
| - f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL)); | 
| + f2_.CreateAnswer(offer.get(), CreatePlanBMediaSessionOptions(), NULL)); | 
| const ContentInfo* ac = answer->GetContentByName("audio"); | 
| const ContentInfo* vc = answer->GetContentByName("video"); | 
| ASSERT_TRUE(ac != NULL); | 
| @@ -849,7 +958,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) { | 
| static_cast<const AudioContentDescription*>(ac->description); | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 
| EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 
| @@ -862,6 +971,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| MediaSessionOptions options; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.crypto_options.enable_gcm_crypto_suites = true; | 
| std::unique_ptr<SessionDescription> offer( | 
| f1_.CreateOffer(options, NULL)); | 
| @@ -877,7 +988,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { | 
| static_cast<const AudioContentDescription*>(ac->description); | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 
| EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); | 
| @@ -887,7 +998,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { | 
| // Create a typical video answer, and ensure it matches what we expect. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| @@ -907,12 +1021,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 
| EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); | 
| - EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 
| EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); | 
| @@ -937,8 +1051,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmAnswer) { | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) { | 
| - MediaSessionOptions opts; | 
| + MediaSessionOptions opts = CreatePlanBMediaSessionOptions(); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| @@ -958,20 +1074,22 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) { | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 
| EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), dcd->codecs()); | 
| - EXPECT_NE(0U, dcd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, dcd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(dcd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(dcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 
| EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), dcd->protocol()); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerGcm) { | 
| - MediaSessionOptions opts; | 
| + MediaSessionOptions opts = CreatePlanBMediaSessionOptions(); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| opts.crypto_options.enable_gcm_crypto_suites = true; | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| @@ -992,12 +1110,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerGcm) { | 
| EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 
| EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 
| - EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); | 
| EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type()); | 
| EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), dcd->codecs()); | 
| - EXPECT_NE(0U, dcd->first_ssrc()); // a random nonzero ssrc | 
| + EXPECT_EQ(0U, dcd->first_ssrc()); // no sender is attached | 
| EXPECT_TRUE(dcd->rtcp_mux()); // negotiated rtcp-mux | 
| ASSERT_CRYPTO(dcd, 1U, CS_AEAD_AES_256_GCM); | 
| EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), dcd->protocol()); | 
| @@ -1008,6 +1126,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerGcm) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerUsesSctpmap) { | 
| MediaSessionOptions opts; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| ContentInfo* dc_offer = offer->GetContentByName("data"); | 
| @@ -1029,6 +1149,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerUsesSctpmap) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerWithoutSctpmap) { | 
| MediaSessionOptions opts; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| ContentInfo* dc_offer = offer->GetContentByName("data"); | 
| @@ -1059,6 +1181,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| MediaSessionOptions opts; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, nullptr)); | 
| ASSERT_TRUE(offer.get() != nullptr); | 
| ContentInfo* dc_offer = offer->GetContentByName("data"); | 
| @@ -1087,19 +1211,22 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAnswerContentOrder) { | 
| MediaSessionOptions opts; | 
| // Creates a data only offer. | 
| - opts.recv_audio = false; | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer1.get() != NULL); | 
| // Appends audio to the offer. | 
| - opts.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer2( | 
| f1_.CreateOffer(opts, offer1.get())); | 
| ASSERT_TRUE(offer2.get() != NULL); | 
| // Appends video to the offer. | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer3( | 
| f1_.CreateOffer(opts, offer2.get())); | 
| ASSERT_TRUE(offer3.get() != NULL); | 
| @@ -1145,7 +1272,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| CreateDataAnswerToOfferWithUnknownProtocol) { | 
| MediaSessionOptions opts; | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| @@ -1171,7 +1299,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // Test that the media protocol is RTP/AVPF if DTLS and SDES are disabled. | 
| TEST_F(MediaSessionDescriptionFactoryTest, AudioOfferAnswerWithCryptoDisabled) { | 
| - MediaSessionOptions opts; | 
| + MediaSessionOptions opts = CreatePlanBMediaSessionOptions(); | 
| f1_.set_secure(SEC_DISABLED); | 
| f2_.set_secure(SEC_DISABLED); | 
| tdf1_.set_secure(SEC_DISABLED); | 
| @@ -1200,8 +1328,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, AudioOfferAnswerWithCryptoDisabled) { | 
| // matches what we expect. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithRtpExtensions) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); | 
| f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); | 
| f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2)); | 
| @@ -1229,7 +1359,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithRtpExtensions) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestOfferAnswerWithEncryptedRtpExtensionsBoth) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_enable_encrypted_rtp_header_extensions(true); | 
| f2_.set_enable_encrypted_rtp_header_extensions(true); | 
| @@ -1265,7 +1398,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestOfferAnswerWithEncryptedRtpExtensionsOffer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_enable_encrypted_rtp_header_extensions(true); | 
| @@ -1300,7 +1436,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestOfferAnswerWithEncryptedRtpExtensionsAnswer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f2_.set_enable_encrypted_rtp_header_extensions(true); | 
| @@ -1336,10 +1475,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestCreateAnswerWithoutLegacyStreams) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| - f1_.set_add_legacy_streams(false); | 
| - f2_.set_add_legacy_streams(false); | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| std::unique_ptr<SessionDescription> answer( | 
| @@ -1363,8 +1505,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestPartial) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| @@ -1401,10 +1548,20 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestPartial) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerRtcpMux) { | 
| MediaSessionOptions offer_opts; | 
| MediaSessionOptions answer_opts; | 
| - answer_opts.recv_video = true; | 
| - offer_opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| answer_opts.data_channel_type = cricket::DCT_RTP; | 
| offer_opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
If these options are identical, could just use the
 
Zhi Huang
2017/08/02 04:38:35
Done.
 | 
| std::unique_ptr<SessionDescription> offer; | 
| std::unique_ptr<SessionDescription> answer; | 
| @@ -1485,11 +1642,20 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerRtcpMux) { | 
| // Create an audio-only answer to a video offer. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerToVideo) { | 
| MediaSessionOptions opts; | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
nit: rename to "offer_opts", to match "answer_opts
 
Zhi Huang
2017/08/02 04:38:36
Done.
 | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| + | 
| + MediaSessionOptions answer_opts; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, answer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, false /*recv*/, | 
| + true /*stopped*/, answer_opts); | 
| std::unique_ptr<SessionDescription> answer( | 
| - f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL)); | 
| + f2_.CreateAnswer(offer.get(), answer_opts, NULL)); | 
| const ContentInfo* ac = answer->GetContentByName("audio"); | 
| const ContentInfo* vc = answer->GetContentByName("video"); | 
| ASSERT_TRUE(ac != NULL); | 
| @@ -1500,12 +1666,19 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerToVideo) { | 
| // Create an audio-only answer to an offer with data. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateNoDataAnswerToDataOffer) { | 
| - MediaSessionOptions opts; | 
| + MediaSessionOptions opts = CreatePlanBMediaSessionOptions(); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| + | 
| + MediaSessionOptions answer_opts = CreatePlanBMediaSessionOptions(); | 
| + answer_opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, false /*recv*/, | 
| + true /*stopped*/, answer_opts); | 
| std::unique_ptr<SessionDescription> answer( | 
| - f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL)); | 
| + f2_.CreateAnswer(offer.get(), answer_opts, NULL)); | 
| const ContentInfo* ac = answer->GetContentByName("audio"); | 
| const ContentInfo* dc = answer->GetContentByName("data"); | 
| ASSERT_TRUE(ac != NULL); | 
| @@ -1518,8 +1691,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateNoDataAnswerToDataOffer) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| CreateAnswerToOfferWithRejectedMedia) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| ContentInfo* ac = offer->GetContentByName("audio"); | 
| @@ -1552,12 +1730,24 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // adding a new video track and replaces one of the audio tracks. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { | 
| MediaSessionOptions opts; | 
| - opts.AddSendStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1); | 
| - opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | 
| - opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack2, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, kVideoTrack1, | 
| + kMediaStream1, 1, opts); | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack1, | 
| + kMediaStream1, 1, opts); | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack2, | 
| + kMediaStream1, 1, opts); | 
| + | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| - opts.AddSendStream(MEDIA_TYPE_DATA, kDataTrack1, kMediaStream1); | 
| - opts.AddSendStream(MEDIA_TYPE_DATA, kDataTrack2, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AttachSenderToMediaSection("data", MEDIA_TYPE_DATA, kDataTrack1, | 
| + kMediaStream1, 1, opts); | 
| + AttachSenderToMediaSection("data", MEDIA_TYPE_DATA, kDataTrack2, | 
| + kMediaStream1, 1, opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| @@ -1622,14 +1812,16 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { | 
| EXPECT_TRUE(dcd->rtcp_mux()); // rtcp-mux defaults on | 
| ASSERT_CRYPTO(dcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 
| - | 
| // Update the offer. Add a new video track that is not synched to the | 
| // other tracks and replace audio track 2 with audio track 3. | 
| - opts.AddSendStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2); | 
| - opts.RemoveSendStream(MEDIA_TYPE_AUDIO, kAudioTrack2); | 
| - opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack3, kMediaStream1); | 
| - opts.RemoveSendStream(MEDIA_TYPE_DATA, kDataTrack2); | 
| - opts.AddSendStream(MEDIA_TYPE_DATA, kDataTrack3, kMediaStream1); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, kVideoTrack2, | 
| + kMediaStream2, 1, opts); | 
| + DetachSenderFromMediaSection("audio", kAudioTrack2, opts); | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack3, | 
| + kMediaStream1, 1, opts); | 
| + DetachSenderFromMediaSection("data", kDataTrack2, opts); | 
| + AttachSenderToMediaSection("data", MEDIA_TYPE_DATA, kDataTrack3, | 
| + kMediaStream1, 1, opts); | 
| std::unique_ptr<SessionDescription> updated_offer( | 
| f1_.CreateOffer(opts, offer.get())); | 
| @@ -1691,8 +1883,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { | 
| // Create an offer with simulcast video stream. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSimulcastVideoOffer) { | 
| MediaSessionOptions opts; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| const int num_sim_layers = 3; | 
| - opts.AddSendVideoStream(kVideoTrack1, kMediaStream1, num_sim_layers); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, kVideoTrack1, | 
| + kMediaStream1, num_sim_layers, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| @@ -1718,19 +1915,35 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSimulcastVideoOffer) { | 
| // adding a new video track and removes one of the audio tracks. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { | 
| MediaSessionOptions offer_opts; | 
| - offer_opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| offer_opts.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, offer_opts); | 
| f1_.set_secure(SEC_ENABLED); | 
| f2_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(offer_opts, NULL)); | 
| MediaSessionOptions opts; | 
| - opts.AddSendStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1); | 
| - opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | 
| - opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack2, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, kVideoTrack1, | 
| + kMediaStream1, 1, opts); | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack1, | 
| + kMediaStream1, 1, opts); | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack2, | 
| + kMediaStream1, 1, opts); | 
| opts.data_channel_type = cricket::DCT_RTP; | 
| - opts.AddSendStream(MEDIA_TYPE_DATA, kDataTrack1, kMediaStream1); | 
| - opts.AddSendStream(MEDIA_TYPE_DATA, kDataTrack2, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AttachSenderToMediaSection("data", MEDIA_TYPE_DATA, kDataTrack1, | 
| + kMediaStream1, 1, opts); | 
| + AttachSenderToMediaSection("data", MEDIA_TYPE_DATA, kDataTrack2, | 
| + kMediaStream1, 1, opts); | 
| std::unique_ptr<SessionDescription> answer( | 
| f2_.CreateAnswer(offer.get(), opts, NULL)); | 
| @@ -1797,9 +2010,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { | 
| // Update the answer. Add a new video track that is not synched to the | 
| // other tracks and remove 1 audio track. | 
| - opts.AddSendStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2); | 
| - opts.RemoveSendStream(MEDIA_TYPE_AUDIO, kAudioTrack2); | 
| - opts.RemoveSendStream(MEDIA_TYPE_DATA, kDataTrack2); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, kVideoTrack2, | 
| + kMediaStream2, 1, opts); | 
| + DetachSenderFromMediaSection("audio", kAudioTrack2, opts); | 
| + DetachSenderFromMediaSection("data", kDataTrack2, opts); | 
| std::unique_ptr<SessionDescription> updated_answer( | 
| f2_.CreateAnswer(offer.get(), opts, answer.get())); | 
| @@ -1853,8 +2067,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| RespondentCreatesOfferAfterCreatingAnswer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| std::unique_ptr<SessionDescription> answer( | 
| @@ -1905,8 +2121,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| RespondentCreatesOfferAfterCreatingAnswerWithRtx) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f1_codecs = MAKE_VECTOR(kVideoCodecs1); | 
| // This creates rtx for H264 with the payload type |f1_| uses. | 
| AddRtxCodec(VideoCodec::CreateRtxCodec(126, kVideoCodecs1[1].id), &f1_codecs); | 
| @@ -1958,8 +2174,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| f1_.set_video_codecs(f1_codecs); | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = false; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 
| std::unique_ptr<SessionDescription> answer( | 
| @@ -1972,8 +2188,11 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // Now - let |f2_| add video with RTX and let the payload type the RTX codec | 
| // reference be the same as an audio codec that was negotiated in the | 
| // first offer/answer exchange. | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + opts.media_description_options.clear(); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f2_codecs = MAKE_VECTOR(kVideoCodecs2); | 
| int used_pl_type = acd->codecs()[0].id; | 
| @@ -2010,8 +2229,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| RespondentCreatesOfferWithRtxAfterCreatingAnswerWithoutRtx) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f2_codecs = MAKE_VECTOR(kVideoCodecs2); | 
| // This creates rtx for H264 with the payload type |f2_| uses. | 
| @@ -2049,8 +2270,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // Test that RTX is ignored when there is no associated payload type parameter. | 
| TEST_F(MediaSessionDescriptionFactoryTest, RtxWithoutApt) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f1_codecs = MAKE_VECTOR(kVideoCodecs1); | 
| // This creates RTX without associated payload type parameter. | 
| AddRtxCodec(VideoCodec(126, cricket::kRtxCodecName), &f1_codecs); | 
| @@ -2093,8 +2314,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtxWithoutApt) { | 
| // type doesn't match the local value. | 
| TEST_F(MediaSessionDescriptionFactoryTest, FilterOutRtxIfAptDoesntMatch) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f1_codecs = MAKE_VECTOR(kVideoCodecs1); | 
| // This creates RTX for H264 in sender. | 
| AddRtxCodec(VideoCodec::CreateRtxCodec(126, kVideoCodecs1[1].id), &f1_codecs); | 
| @@ -2123,8 +2344,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, FilterOutRtxIfAptDoesntMatch) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| FilterOutUnsupportedRtxWhenCreatingAnswer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f1_codecs = MAKE_VECTOR(kVideoCodecs1); | 
| // This creates RTX for H264-SVC in sender. | 
| AddRtxCodec(VideoCodec::CreateRtxCodec(125, kVideoCodecs1[0].id), &f1_codecs); | 
| @@ -2158,8 +2379,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // to add another. | 
| TEST_F(MediaSessionDescriptionFactoryTest, AddSecondRtxInNewOffer) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::vector<VideoCodec> f1_codecs = MAKE_VECTOR(kVideoCodecs1); | 
| // This creates RTX for H264 for the offerer. | 
| AddRtxCodec(VideoCodec::CreateRtxCodec(126, kVideoCodecs1[1].id), &f1_codecs); | 
| @@ -2193,11 +2414,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, AddSecondRtxInNewOffer) { | 
| // generated for each simulcast ssrc and correctly grouped. | 
| TEST_F(MediaSessionDescriptionFactoryTest, SimSsrcsGenerateMultipleRtxSsrcs) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| // Add simulcast streams. | 
| - opts.AddSendVideoStream("stream1", "stream1label", 3); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, "stream1", | 
| + "stream1label", 3, opts); | 
| // Use a single real codec, and then add RTX for it. | 
| std::vector<VideoCodec> f1_codecs; | 
| @@ -2234,11 +2456,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, SimSsrcsGenerateMultipleRtxSsrcs) { | 
| // together with a FEC-FR grouping. | 
| TEST_F(MediaSessionDescriptionFactoryTest, GenerateFlexfecSsrc) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| // Add single stream. | 
| - opts.AddSendVideoStream("stream1", "stream1label", 1); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, "stream1", | 
| + "stream1label", 1, opts); | 
| // Use a single real codec, and then add FlexFEC for it. | 
| std::vector<VideoCodec> f1_codecs; | 
| @@ -2274,11 +2497,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, GenerateFlexfecSsrc) { | 
| // multiple FlexfecSenders, or through multistream protection. | 
| TEST_F(MediaSessionDescriptionFactoryTest, SimSsrcsGenerateNoFlexfecSsrcs) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| - opts.recv_audio = false; | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| // Add simulcast streams. | 
| - opts.AddSendVideoStream("stream1", "stream1label", 3); | 
| + AttachSenderToMediaSection("video", MEDIA_TYPE_VIDEO, "stream1", | 
| + "stream1label", 3, opts); | 
| // Use a single real codec, and then add FlexFEC for it. | 
| std::vector<VideoCodec> f1_codecs; | 
| @@ -2318,8 +2542,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, SimSsrcsGenerateNoFlexfecSsrcs) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| RespondentCreatesOfferAfterCreatingAnswerWithRtpExtensions) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); | 
| f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); | 
| @@ -2373,8 +2599,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| // updated offer (this was previously a bug). | 
| TEST_F(MediaSessionDescriptionFactoryTest, RtpExtensionIdReused) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension3)); | 
| f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension3)); | 
| @@ -2409,8 +2637,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtensionIdReused) { | 
| // Same as "RtpExtensionIdReused" above for encrypted RTP extensions. | 
| TEST_F(MediaSessionDescriptionFactoryTest, RtpExtensionIdReusedEncrypted) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| f1_.set_enable_encrypted_rtp_header_extensions(true); | 
| f2_.set_enable_encrypted_rtp_header_extensions(true); | 
| @@ -2486,45 +2716,62 @@ TEST(MediaSessionDescription, CopySessionDescription) { | 
| // ensure the TransportInfo in the SessionDescription matches what we expect. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoOfferAudio) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(true, options, false); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoOfferIceRenomination) { | 
| MediaSessionOptions options; | 
| - options.enable_ice_renomination = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + auto media_desc_options_it = options.FindMediaDescription("audio"); | 
| + media_desc_options_it->transport_options.enable_ice_renomination = true; | 
| TestTransportInfo(true, options, false); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoOfferAudioCurrent) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(true, options, true); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoOfferMultimedia) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(true, options, false); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoOfferMultimediaCurrent) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(true, options, true); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoOfferBundle) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.bundle_enabled = true; | 
| TestTransportInfo(true, options, false); | 
| } | 
| @@ -2532,55 +2779,76 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoOfferBundle) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoOfferBundleCurrent) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.bundle_enabled = true; | 
| TestTransportInfo(true, options, true); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoAnswerAudio) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(false, options, false); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoAnswerIceRenomination) { | 
| MediaSessionOptions options; | 
| - options.enable_ice_renomination = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + auto media_desc_options_it = options.FindMediaDescription("audio"); | 
| + media_desc_options_it->transport_options.enable_ice_renomination = true; | 
| TestTransportInfo(false, options, false); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoAnswerAudioCurrent) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(false, options, true); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoAnswerMultimedia) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(false, options, false); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoAnswerMultimediaCurrent) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| TestTransportInfo(false, options, true); | 
| } | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoAnswerBundle) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.bundle_enabled = true; | 
| TestTransportInfo(false, options, false); | 
| } | 
| @@ -2588,9 +2856,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfoAnswerBundle) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestTransportInfoAnswerBundleCurrent) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.bundle_enabled = true; | 
| TestTransportInfo(false, options, true); | 
| } | 
| @@ -2617,7 +2889,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| tdf2_.set_secure(SEC_DISABLED); | 
| std::unique_ptr<SessionDescription> offer( | 
| - f1_.CreateOffer(MediaSessionOptions(), NULL)); | 
| + f1_.CreateOffer(CreatePlanBMediaSessionOptions(), NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| ContentInfo* offer_content = offer->GetContentByName("audio"); | 
| ASSERT_TRUE(offer_content != NULL); | 
| @@ -2626,7 +2898,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| offer_audio_desc->set_protocol(cricket::kMediaProtocolDtlsSavpf); | 
| std::unique_ptr<SessionDescription> answer( | 
| - f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL)); | 
| + f2_.CreateAnswer(offer.get(), CreatePlanBMediaSessionOptions(), NULL)); | 
| ASSERT_TRUE(answer != NULL); | 
| ContentInfo* answer_content = answer->GetContentByName("audio"); | 
| ASSERT_TRUE(answer_content != NULL); | 
| @@ -2643,7 +2915,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) { | 
| tdf2_.set_secure(SEC_ENABLED); | 
| std::unique_ptr<SessionDescription> offer( | 
| - f1_.CreateOffer(MediaSessionOptions(), NULL)); | 
| + f1_.CreateOffer(CreatePlanBMediaSessionOptions(), NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| ContentInfo* offer_content = offer->GetContentByName("audio"); | 
| ASSERT_TRUE(offer_content != NULL); | 
| @@ -2652,7 +2924,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) { | 
| offer_audio_desc->set_protocol(cricket::kMediaProtocolDtlsSavpf); | 
| std::unique_ptr<SessionDescription> answer( | 
| - f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL)); | 
| + f2_.CreateAnswer(offer.get(), CreatePlanBMediaSessionOptions(), NULL)); | 
| ASSERT_TRUE(answer != NULL); | 
| const ContentInfo* answer_content = answer->GetContentByName("audio"); | 
| @@ -2673,8 +2945,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoDtls) { | 
| tdf1_.set_secure(SEC_ENABLED); | 
| tdf2_.set_secure(SEC_DISABLED); | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| std::unique_ptr<SessionDescription> offer, answer; | 
| const cricket::MediaContentDescription* audio_media_desc; | 
| const cricket::MediaContentDescription* video_media_desc; | 
| @@ -2770,7 +3044,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoDtls) { | 
| // Test that an answer can't be created if cryptos are required but the offer is | 
| // unsecure. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestSecureAnswerToUnsecureOffer) { | 
| - MediaSessionOptions options; | 
| + MediaSessionOptions options = CreatePlanBMediaSessionOptions(); | 
| f1_.set_secure(SEC_DISABLED); | 
| tdf1_.set_secure(SEC_DISABLED); | 
| f2_.set_secure(SEC_REQUIRED); | 
| @@ -2791,9 +3065,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoOfferDtlsButNotSdes) { | 
| tdf1_.set_secure(SEC_ENABLED); | 
| tdf2_.set_secure(SEC_ENABLED); | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| options.data_channel_type = cricket::DCT_RTP; | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| std::unique_ptr<SessionDescription> offer, answer; | 
| @@ -2840,8 +3118,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoOfferDtlsButNotSdes) { | 
| // offer or answer. | 
| TEST_F(MediaSessionDescriptionFactoryTest, TestVADEnableOption) { | 
| MediaSessionOptions options; | 
| - options.recv_audio = true; | 
| - options.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, options); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(options, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| const ContentInfo* audio_content = offer->GetContentByName("audio"); | 
| @@ -2864,14 +3144,15 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestVADEnableOption) { | 
| TEST_F(MediaSessionDescriptionFactoryTest, | 
| TestContentNameNotChangedInSubsequentOffers) { | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = true; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| opts.data_channel_type = cricket::DCT_SCTP; | 
| - // Create offer and modify the default content names. | 
| + AddMediaSection(MEDIA_TYPE_DATA, "data", true /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + // Create offer. | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, nullptr)); | 
| - for (ContentInfo& content : offer->contents()) { | 
| - content.name.append("_modified"); | 
| - } | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
What this test is really verifying is that MIDs ar
 
Zhi Huang
2017/08/02 04:38:36
I'll use some non-default MIDs for this tests. 
Bu
 | 
| std::unique_ptr<SessionDescription> updated_offer( | 
| f1_.CreateOffer(opts, offer.get())); | 
| @@ -2881,9 +3162,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, | 
| ASSERT_TRUE(audio_content != nullptr); | 
| ASSERT_TRUE(video_content != nullptr); | 
| ASSERT_TRUE(data_content != nullptr); | 
| - EXPECT_EQ("audio_modified", audio_content->name); | 
| - EXPECT_EQ("video_modified", video_content->name); | 
| - EXPECT_EQ("data_modified", data_content->name); | 
| + EXPECT_EQ("audio", audio_content->name); | 
| + EXPECT_EQ("video", video_content->name); | 
| + EXPECT_EQ("data", data_content->name); | 
| } | 
| class MediaProtocolTest : public ::testing::TestWithParam<const char*> { | 
| @@ -2916,7 +3197,10 @@ class MediaProtocolTest : public ::testing::TestWithParam<const char*> { | 
| TEST_P(MediaProtocolTest, TestAudioVideoAcceptance) { | 
| MediaSessionOptions opts; | 
| - opts.recv_video = true; | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, true /*recv*/, | 
| + false /*stopped*/, opts); | 
| std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, nullptr)); | 
| ASSERT_TRUE(offer.get() != nullptr); | 
| // Set the protocol for all the contents. | 
| @@ -2976,32 +3260,31 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestSetAudioCodecs) { | 
| // Test proper merge | 
| sf.set_audio_codecs(send_codecs, recv_codecs); | 
| - EXPECT_TRUE(sf.audio_send_codecs() == send_codecs); | 
| - EXPECT_TRUE(sf.audio_recv_codecs() == recv_codecs); | 
| - EXPECT_TRUE(sf.audio_sendrecv_codecs() == sendrecv_codecs); | 
| + EXPECT_EQ(send_codecs, sf.audio_send_codecs()); | 
| + EXPECT_EQ(recv_codecs, sf.audio_recv_codecs()); | 
| + EXPECT_EQ(sendrecv_codecs, sf.audio_sendrecv_codecs()); | 
| // Test empty send codecs list | 
| sf.set_audio_codecs(no_codecs, recv_codecs); | 
| - EXPECT_TRUE(sf.audio_send_codecs() == no_codecs); | 
| - EXPECT_TRUE(sf.audio_recv_codecs() == recv_codecs); | 
| - EXPECT_TRUE(sf.audio_sendrecv_codecs() == no_codecs); | 
| + EXPECT_EQ(no_codecs, sf.audio_send_codecs()); | 
| + EXPECT_EQ(recv_codecs, sf.audio_recv_codecs()); | 
| + EXPECT_EQ(no_codecs, sf.audio_sendrecv_codecs()); | 
| // Test empty recv codecs list | 
| sf.set_audio_codecs(send_codecs, no_codecs); | 
| - EXPECT_TRUE(sf.audio_send_codecs() == send_codecs); | 
| - EXPECT_TRUE(sf.audio_recv_codecs() == no_codecs); | 
| - EXPECT_TRUE(sf.audio_sendrecv_codecs() == no_codecs); | 
| + EXPECT_EQ(send_codecs, sf.audio_send_codecs()); | 
| + EXPECT_EQ(no_codecs, sf.audio_recv_codecs()); | 
| + EXPECT_EQ(no_codecs, sf.audio_sendrecv_codecs()); | 
| // Test all empty codec lists | 
| sf.set_audio_codecs(no_codecs, no_codecs); | 
| - EXPECT_TRUE(sf.audio_send_codecs() == no_codecs); | 
| - EXPECT_TRUE(sf.audio_recv_codecs() == no_codecs); | 
| - EXPECT_TRUE(sf.audio_sendrecv_codecs() == no_codecs); | 
| + EXPECT_EQ(no_codecs, sf.audio_send_codecs()); | 
| + EXPECT_EQ(no_codecs, sf.audio_recv_codecs()); | 
| + EXPECT_EQ(no_codecs, sf.audio_sendrecv_codecs()); | 
| } | 
| namespace { | 
| -void TestAudioCodecsOffer(MediaContentDirection direction, | 
| - bool add_legacy_stream) { | 
| +void TestAudioCodecsOffer(MediaContentDirection direction) { | 
| TransportDescriptionFactory tdf; | 
| MediaSessionDescriptionFactory sf(&tdf); | 
| const std::vector<AudioCodec> send_codecs = MAKE_VECTOR(kAudioCodecs1); | 
| @@ -3009,14 +3292,19 @@ void TestAudioCodecsOffer(MediaContentDirection direction, | 
| const std::vector<AudioCodec> sendrecv_codecs = | 
| MAKE_VECTOR(kAudioCodecsAnswer); | 
| sf.set_audio_codecs(send_codecs, recv_codecs); | 
| - sf.set_add_legacy_streams(add_legacy_stream); | 
| MediaSessionOptions opts; | 
| - opts.recv_audio = (direction == cricket::MD_RECVONLY || | 
| - direction == cricket::MD_SENDRECV); | 
| - opts.recv_video = false; | 
| - if (direction == cricket::MD_SENDONLY || direction == cricket::MD_SENDRECV) | 
| - opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | 
| + bool recv_audio = | 
| + (direction == cricket::MD_RECVONLY || direction == cricket::MD_SENDRECV); | 
| + bool send_audio = | 
| + (direction == cricket::MD_SENDONLY || direction == cricket::MD_SENDRECV); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", send_audio, recv_audio, | 
| + false /*stopped*/, opts); | 
| + | 
| + if (send_audio) { | 
| 
Taylor Brandstetter
2017/07/28 01:19:39
To extract the send/recv direction easily, you can
 
Zhi Huang
2017/08/02 04:38:36
Done.
 | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack1, | 
| + kMediaStream1, 1, opts); | 
| + } | 
| std::unique_ptr<SessionDescription> offer(sf.CreateOffer(opts, NULL)); | 
| ASSERT_TRUE(offer.get() != NULL); | 
| @@ -3033,11 +3321,11 @@ void TestAudioCodecsOffer(MediaContentDirection direction, | 
| // be used for sending and receiving. Inactive essentially means it might | 
| // eventually be used anything, but we don't know more at this moment. | 
| if (acd->direction() == cricket::MD_SENDONLY) { | 
| - EXPECT_TRUE(acd->codecs() == send_codecs); | 
| + EXPECT_EQ(send_codecs, acd->codecs()); | 
| } else if (acd->direction() == cricket::MD_RECVONLY) { | 
| - EXPECT_TRUE(acd->codecs() == recv_codecs); | 
| + EXPECT_EQ(recv_codecs, acd->codecs()); | 
| } else { | 
| - EXPECT_TRUE(acd->codecs() == sendrecv_codecs); | 
| + EXPECT_EQ(sendrecv_codecs, acd->codecs()); | 
| } | 
| } | 
| } | 
| @@ -3109,17 +3397,21 @@ void TestAudioCodecsAnswer(MediaContentDirection offer_direction, | 
| VectorFromIndices(kOfferAnswerCodecs, kAnswerSendCodecs), | 
| VectorFromIndices(kOfferAnswerCodecs, kAnswerRecvCodecs)); | 
| - // Never add a legacy stream to offer - we want to control the offer | 
| - // parameters exactly. | 
| - offer_factory.set_add_legacy_streams(false); | 
| - answer_factory.set_add_legacy_streams(add_legacy_stream); | 
| MediaSessionOptions offer_opts; | 
| - offer_opts.recv_audio = (offer_direction == cricket::MD_RECVONLY || | 
| + | 
| + bool offer_recv_audio = (offer_direction == cricket::MD_RECVONLY || | 
| + offer_direction == cricket::MD_SENDRECV); | 
| + bool offer_send_audio = (offer_direction == cricket::MD_SENDONLY || | 
| offer_direction == cricket::MD_SENDRECV); | 
| - offer_opts.recv_video = false; | 
| - if (offer_direction == cricket::MD_SENDONLY || | 
| - offer_direction == cricket::MD_SENDRECV) { | 
| - offer_opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", offer_send_audio, offer_recv_audio, | 
| + false /*stopped*/, offer_opts); | 
| + | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, false /*recv*/, | 
| + true /*stopped*/, offer_opts); | 
| + | 
| + if (offer_send_audio) { | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack1, | 
| + kMediaStream1, 1, offer_opts); | 
| } | 
| std::unique_ptr<SessionDescription> offer( | 
| @@ -3127,12 +3419,19 @@ void TestAudioCodecsAnswer(MediaContentDirection offer_direction, | 
| ASSERT_TRUE(offer.get() != NULL); | 
| MediaSessionOptions answer_opts; | 
| - answer_opts.recv_audio = (answer_direction == cricket::MD_RECVONLY || | 
| + bool answer_recv_audio = (answer_direction == cricket::MD_RECVONLY || | 
| + answer_direction == cricket::MD_SENDRECV); | 
| + bool answer_send_audio = (answer_direction == cricket::MD_SENDONLY || | 
| answer_direction == cricket::MD_SENDRECV); | 
| - answer_opts.recv_video = false; | 
| - if (answer_direction == cricket::MD_SENDONLY || | 
| - answer_direction == cricket::MD_SENDRECV) { | 
| - answer_opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | 
| + AddMediaSection(MEDIA_TYPE_AUDIO, "audio", answer_send_audio, | 
| + answer_recv_audio, false /*stopped*/, answer_opts); | 
| + | 
| + AddMediaSection(MEDIA_TYPE_VIDEO, "video", false /*send*/, false /*recv*/, | 
| + true /*stopped*/, answer_opts); | 
| + | 
| + if (answer_send_audio) { | 
| + AttachSenderToMediaSection("audio", MEDIA_TYPE_AUDIO, kAudioTrack1, | 
| + kMediaStream1, 1, answer_opts); | 
| } | 
| std::unique_ptr<SessionDescription> answer( | 
| answer_factory.CreateAnswer(offer.get(), answer_opts, NULL)); | 
| @@ -3206,23 +3505,18 @@ void TestAudioCodecsAnswer(MediaContentDirection offer_direction, | 
| } // namespace | 
| class AudioCodecsOfferTest | 
| - : public ::testing::TestWithParam<::testing::tuple<MediaContentDirection, | 
| - bool>> { | 
| -}; | 
| + : public ::testing::TestWithParam<MediaContentDirection> {}; | 
| TEST_P(AudioCodecsOfferTest, TestCodecsInOffer) { | 
| - TestAudioCodecsOffer(::testing::get<0>(GetParam()), | 
| - ::testing::get<1>(GetParam())); | 
| + TestAudioCodecsOffer(GetParam()); | 
| } | 
| INSTANTIATE_TEST_CASE_P(MediaSessionDescriptionFactoryTest, | 
| AudioCodecsOfferTest, | 
| - ::testing::Combine( | 
| - ::testing::Values(cricket::MD_SENDONLY, | 
| - cricket::MD_RECVONLY, | 
| - cricket::MD_SENDRECV, | 
| - cricket::MD_INACTIVE), | 
| - ::testing::Bool())); | 
| + ::testing::Values(cricket::MD_SENDONLY, | 
| + cricket::MD_RECVONLY, | 
| + cricket::MD_SENDRECV, | 
| + cricket::MD_INACTIVE)); | 
| class AudioCodecsAnswerTest | 
| : public ::testing::TestWithParam<::testing::tuple<MediaContentDirection, |