--- a/media/webrtc/signaling/gtest/jsep_session_unittest.cpp
+++ b/media/webrtc/signaling/gtest/jsep_session_unittest.cpp
@@ -230,16 +230,24 @@ protected:
void
AddTracks(JsepSessionImpl& side, AddTrackMagic magic = ADDTRACK_MAGIC)
{
// Add tracks.
if (types.empty()) {
types = BuildTypes(GetParam());
}
AddTracks(side, types, magic);
+
+ // Now, we move datachannel to the end
+ auto it = std::find(types.begin(), types.end(),
+ SdpMediaSection::kApplication);
+ if (it != types.end()) {
+ types.erase(it);
+ types.push_back(SdpMediaSection::kApplication);
+ }
}
void
AddTracks(JsepSessionImpl& side,
const std::string& mediatypes,
AddTrackMagic magic = ADDTRACK_MAGIC)
{
AddTracks(side, BuildTypes(mediatypes), magic);
@@ -277,27 +285,25 @@ protected:
{
std::vector<SdpMediaSection::MediaType> result;
size_t ptr = 0;
for (;;) {
size_t comma = mediatypes.find(',', ptr);
std::string chunk = mediatypes.substr(ptr, comma - ptr);
- SdpMediaSection::MediaType type;
if (chunk == "audio") {
- type = SdpMediaSection::kAudio;
+ result.push_back(SdpMediaSection::kAudio);
} else if (chunk == "video") {
- type = SdpMediaSection::kVideo;
+ result.push_back(SdpMediaSection::kVideo);
} else if (chunk == "datachannel") {
- type = SdpMediaSection::kApplication;
+ result.push_back(SdpMediaSection::kApplication);
} else {
MOZ_CRASH();
}
- result.push_back(type);
if (comma == std::string::npos)
break;
ptr = comma + 1;
}
return result;
}
@@ -350,17 +356,17 @@ protected:
size_t i = transceivers.size();
if (magic == ADDTRACK_MAGIC) {
for (i = 0; i < transceivers.size(); ++i) {
if (transceivers[i]->mSendTrack.GetMediaType() != type) {
continue;
}
if (IsNull(transceivers[i]->mSendTrack) ||
- type == SdpMediaSection::MediaType::kApplication) {
+ transceivers[i]->GetMediaType() == SdpMediaSection::kApplication) {
break;
}
}
}
if (i == transceivers.size()) {
side.AddTransceiver(new JsepTransceiver(type));
MOZ_ASSERT(i < transceivers.size());
@@ -437,16 +443,34 @@ protected:
return transceiver.get();
}
}
return nullptr;
}
+ JsepTransceiver*
+ GetTransceiverByLevel(
+ const std::vector<RefPtr<JsepTransceiver>>& transceivers,
+ size_t level) {
+ for (auto& transceiver : transceivers) {
+ if (transceiver->HasLevel() && transceiver->GetLevel() == level) {
+ return transceiver.get();
+ }
+ }
+
+ return nullptr;
+ }
+
+ JsepTransceiver*
+ GetTransceiverByLevel(JsepSession& side, size_t level) {
+ return GetTransceiverByLevel(side.GetTransceivers(), level);
+ }
+
std::vector<std::string>
GetMediaStreamIds(const std::vector<JsepTrack>& tracks) const {
std::vector<std::string> ids;
for (const auto& track : tracks) {
// data channels don't have msid's
if (track.GetMediaType() == SdpMediaSection::kApplication) {
continue;
}
@@ -1390,17 +1414,17 @@ protected:
std::cerr << std::endl;
}
}
}
void
DumpTransceivers(const JsepSessionImpl& session)
{
- for (const auto& transceiver : mSessionAns->GetTransceivers()) {
+ for (const auto& transceiver : session.GetTransceivers()) {
std::cerr << "Transceiver ";
if (transceiver->HasLevel()) {
std::cerr << transceiver->GetLevel() << std::endl;
} else {
std::cerr << "<NO LEVEL>" << std::endl;
}
if (transceiver->HasBundleLevel()) {
std::cerr << "(bundle level is " << transceiver->BundleLevel() << ")"
@@ -1887,28 +1911,28 @@ TEST_P(JsepSessionTest, RenegotiationBot
// The JSEP draft explicitly forbids changing the msid on an m-section, but
// that is a new restriction that older versions of Firefox do not follow.
// JS will not see the msid change, since that is filtered out (except for
// RTCRtpTransceiver.remoteTrackId)
TEST_P(JsepSessionTest, RenegotiationOffererChangesMsid)
{
AddTracks(*mSessionOff);
AddTracks(*mSessionAns);
- if (types.front() == SdpMediaSection::kApplication) {
- return;
- }
OfferAnswer();
std::string offer = CreateOffer();
SetLocalOffer(offer);
RefPtr<JsepTransceiver> transceiver =
GetNegotiatedTransceiver(*mSessionOff, 0);
ASSERT_TRUE(transceiver);
+ if (transceiver->GetMediaType() == SdpMediaSection::kApplication) {
+ return;
+ }
std::string streamId = transceiver->mSendTrack.GetStreamIds()[0];
std::string trackId = transceiver->mSendTrack.GetTrackId();
std::string msidToReplace("a=msid:");
msidToReplace += streamId;
msidToReplace += " ";
msidToReplace += trackId;
size_t msidOffset = offer.find(msidToReplace);
ASSERT_NE(std::string::npos, msidOffset);
@@ -1925,31 +1949,37 @@ TEST_P(JsepSessionTest, RenegotiationOff
}
// The JSEP draft explicitly forbids changing the msid on an m-section, but
// that is a new restriction that older versions of Firefox do not follow.
TEST_P(JsepSessionTest, RenegotiationAnswererChangesMsid)
{
AddTracks(*mSessionOff);
AddTracks(*mSessionAns);
- if (types.front() == SdpMediaSection::kApplication) {
+
+ OfferAnswer();
+
+ RefPtr<JsepTransceiver> transceiver =
+ GetNegotiatedTransceiver(*mSessionOff, 0);
+ ASSERT_TRUE(transceiver);
+ if (transceiver->GetMediaType() == SdpMediaSection::kApplication) {
return;
}
- OfferAnswer();
-
std::string offer = CreateOffer();
SetLocalOffer(offer);
SetRemoteOffer(offer);
std::string answer = CreateAnswer();
SetLocalAnswer(answer);
- RefPtr<JsepTransceiver> transceiver =
- GetNegotiatedTransceiver(*mSessionAns, 0);
+ transceiver = GetNegotiatedTransceiver(*mSessionAns, 0);
ASSERT_TRUE(transceiver);
+ if (transceiver->GetMediaType() == SdpMediaSection::kApplication) {
+ return;
+ }
std::string streamId = transceiver->mSendTrack.GetStreamIds()[0];
std::string trackId = transceiver->mSendTrack.GetTrackId();
std::string msidToReplace("a=msid:");
msidToReplace += streamId;
msidToReplace += " ";
msidToReplace += trackId;
size_t msidOffset = answer.find(msidToReplace);
ASSERT_NE(std::string::npos, msidOffset);
@@ -2176,18 +2206,20 @@ TEST_P(JsepSessionTest, RenegotiationBot
{
AddTracks(*mSessionOff);
AddTracks(*mSessionAns);
if (types.size() < 2) {
return;
}
- if (types[0] == SdpMediaSection::kApplication ||
- types[1] == SdpMediaSection::kApplication) {
+ if (mSessionOff->GetTransceivers()[0]->GetMediaType() ==
+ SdpMediaSection::kApplication ||
+ mSessionOff->GetTransceivers()[1]->GetMediaType() ==
+ SdpMediaSection::kApplication) {
return;
}
OfferAnswer();
mSessionOff->GetTransceivers()[0]->Stop();
mSessionOff->GetTransceivers()[1]->Stop();
@@ -2196,17 +2228,18 @@ TEST_P(JsepSessionTest, RenegotiationBot
ASSERT_TRUE(mSessionAns->GetTransceivers()[1]->IsStopped());
}
TEST_P(JsepSessionTest, RenegotiationOffererReplacesTrack)
{
AddTracks(*mSessionOff);
AddTracks(*mSessionAns);
- if (types.front() == SdpMediaSection::kApplication) {
+ if (mSessionOff->GetTransceivers()[0]->GetMediaType() ==
+ SdpMediaSection::kApplication) {
return;
}
OfferAnswer();
mSessionOff->GetTransceivers()[0]->mSendTrack.UpdateTrackIds(
std::vector<std::string>(1, "newstream"), "newtrack");
@@ -2220,17 +2253,18 @@ TEST_P(JsepSessionTest, RenegotiationOff
mSessionAns->GetTransceivers()[0]->mRecvTrack.GetStreamIds()[0]);
}
TEST_P(JsepSessionTest, RenegotiationAnswererReplacesTrack)
{
AddTracks(*mSessionOff);
AddTracks(*mSessionAns);
- if (types.front() == SdpMediaSection::kApplication) {
+ if (mSessionOff->GetTransceivers()[0]->GetMediaType() ==
+ SdpMediaSection::kApplication) {
return;
}
OfferAnswer();
mSessionAns->GetTransceivers()[0]->mSendTrack.UpdateTrackIds(
std::vector<std::string>(1, "newstream"), "newtrack");
@@ -2507,52 +2541,56 @@ TEST_P(JsepSessionTest, RenegotiationOff
AddTracks(*mSessionAns);
if (types.size() < 2) {
return;
}
OfferAnswer();
- mSessionOff->GetTransceivers()[0]->Stop();
+ GetTransceiverByLevel(*mSessionOff, 0)->Stop();
std::vector<RefPtr<JsepTransceiver>> origOffererTransceivers
= DeepCopy(mSessionOff->GetTransceivers());
std::vector<RefPtr<JsepTransceiver>> origAnswererTransceivers
= DeepCopy(mSessionAns->GetTransceivers());
OfferAnswer(CHECK_SUCCESS);
auto newOffererTransceivers = mSessionOff->GetTransceivers();
auto newAnswererTransceivers = mSessionAns->GetTransceivers();
ASSERT_EQ(newOffererTransceivers.size(), newAnswererTransceivers.size());
ASSERT_EQ(origOffererTransceivers.size(), newOffererTransceivers.size());
ASSERT_EQ(origAnswererTransceivers.size(), newAnswererTransceivers.size());
- ASSERT_FALSE(newOffererTransceivers[0]->HasBundleLevel());
- ASSERT_FALSE(newAnswererTransceivers[0]->HasBundleLevel());
-
- ASSERT_NE(newOffererTransceivers[0]->mTransport.get(),
- origOffererTransceivers[0]->mTransport.get());
- ASSERT_NE(newAnswererTransceivers[0]->mTransport.get(),
- origAnswererTransceivers[0]->mTransport.get());
-
- ASSERT_EQ(0U, newOffererTransceivers[0]->mTransport->mComponents);
- ASSERT_EQ(0U, newAnswererTransceivers[0]->mTransport->mComponents);
-
- for (size_t i = 1; i < newOffererTransceivers.size(); ++i) {
- ASSERT_TRUE(newOffererTransceivers[i]->HasBundleLevel());
- ASSERT_TRUE(newAnswererTransceivers[i]->HasBundleLevel());
- ASSERT_EQ(1U, newOffererTransceivers[i]->BundleLevel());
- ASSERT_EQ(1U, newAnswererTransceivers[i]->BundleLevel());
- ASSERT_NE(newOffererTransceivers[0]->mTransport.get(),
- newOffererTransceivers[i]->mTransport.get());
- ASSERT_NE(newAnswererTransceivers[0]->mTransport.get(),
- newAnswererTransceivers[i]->mTransport.get());
+ JsepTransceiver* ot0 = GetTransceiverByLevel(newOffererTransceivers, 0);
+ JsepTransceiver* at0 = GetTransceiverByLevel(newAnswererTransceivers, 0);
+ ASSERT_FALSE(ot0->HasBundleLevel());
+ ASSERT_FALSE(at0->HasBundleLevel());
+
+ ASSERT_NE(
+ ot0->mTransport.get(),
+ GetTransceiverByLevel(origOffererTransceivers, 0)->mTransport.get());
+ ASSERT_NE(
+ at0->mTransport.get(),
+ GetTransceiverByLevel(origAnswererTransceivers, 0)->mTransport.get());
+
+ ASSERT_EQ(0U, ot0->mTransport->mComponents);
+ ASSERT_EQ(0U, at0->mTransport->mComponents);
+
+ for (size_t i = 1; i < types.size() - 1; ++i) {
+ JsepTransceiver* ot = GetTransceiverByLevel(newOffererTransceivers, i);
+ JsepTransceiver* at = GetTransceiverByLevel(newAnswererTransceivers, i);
+ ASSERT_TRUE(ot->HasBundleLevel());
+ ASSERT_TRUE(at->HasBundleLevel());
+ ASSERT_EQ(1U, ot->BundleLevel());
+ ASSERT_EQ(1U, at->BundleLevel());
+ ASSERT_NE(ot0->mTransport.get(), ot->mTransport.get());
+ ASSERT_NE(at0->mTransport.get(), at->mTransport.get());
}
}
TEST_P(JsepSessionTest, RenegotiationAnswererDisablesBundleTransport)
{
AddTracks(*mSessionOff);
AddTracks(*mSessionAns);
@@ -2562,47 +2600,51 @@ TEST_P(JsepSessionTest, RenegotiationAns
OfferAnswer();
std::vector<RefPtr<JsepTransceiver>> origOffererTransceivers
= DeepCopy(mSessionOff->GetTransceivers());
std::vector<RefPtr<JsepTransceiver>> origAnswererTransceivers
= DeepCopy(mSessionAns->GetTransceivers());
- mSessionAns->GetTransceivers()[0]->Stop();
+ GetTransceiverByLevel(*mSessionAns, 0)->Stop();
OfferAnswer(CHECK_SUCCESS);
auto newOffererTransceivers = mSessionOff->GetTransceivers();
auto newAnswererTransceivers = mSessionAns->GetTransceivers();
ASSERT_EQ(newOffererTransceivers.size(), newAnswererTransceivers.size());
ASSERT_EQ(origOffererTransceivers.size(), newOffererTransceivers.size());
ASSERT_EQ(origAnswererTransceivers.size(), newAnswererTransceivers.size());
- ASSERT_FALSE(newOffererTransceivers[0]->HasBundleLevel());
- ASSERT_FALSE(newAnswererTransceivers[0]->HasBundleLevel());
-
- ASSERT_NE(newOffererTransceivers[0]->mTransport.get(),
- origOffererTransceivers[0]->mTransport.get());
- ASSERT_NE(newAnswererTransceivers[0]->mTransport.get(),
- origAnswererTransceivers[0]->mTransport.get());
-
- ASSERT_EQ(0U, newOffererTransceivers[0]->mTransport->mComponents);
- ASSERT_EQ(0U, newAnswererTransceivers[0]->mTransport->mComponents);
+ JsepTransceiver* ot0 = GetTransceiverByLevel(newOffererTransceivers, 0);
+ JsepTransceiver* at0 = GetTransceiverByLevel(newAnswererTransceivers, 0);
+ ASSERT_FALSE(ot0->HasBundleLevel());
+ ASSERT_FALSE(at0->HasBundleLevel());
+
+ ASSERT_NE(
+ ot0->mTransport.get(),
+ GetTransceiverByLevel(origOffererTransceivers, 0)->mTransport.get());
+ ASSERT_NE(
+ at0->mTransport.get(),
+ GetTransceiverByLevel(origAnswererTransceivers, 0)->mTransport.get());
+
+ ASSERT_EQ(0U, ot0->mTransport->mComponents);
+ ASSERT_EQ(0U, at0->mTransport->mComponents);
for (size_t i = 1; i < newOffererTransceivers.size(); ++i) {
- ASSERT_TRUE(newOffererTransceivers[i]->HasBundleLevel());
- ASSERT_TRUE(newAnswererTransceivers[i]->HasBundleLevel());
- ASSERT_EQ(1U, newOffererTransceivers[i]->BundleLevel());
- ASSERT_EQ(1U, newAnswererTransceivers[i]->BundleLevel());
- ASSERT_NE(newOffererTransceivers[0]->mTransport.get(),
- newOffererTransceivers[i]->mTransport.get());
- ASSERT_NE(newAnswererTransceivers[0]->mTransport.get(),
- newAnswererTransceivers[i]->mTransport.get());
+ JsepTransceiver* ot = GetTransceiverByLevel(newOffererTransceivers, i);
+ JsepTransceiver* at = GetTransceiverByLevel(newAnswererTransceivers, i);
+ ASSERT_TRUE(ot->HasBundleLevel());
+ ASSERT_TRUE(at->HasBundleLevel());
+ ASSERT_EQ(1U, ot->BundleLevel());
+ ASSERT_EQ(1U, at->BundleLevel());
+ ASSERT_NE(ot0->mTransport.get(), ot->mTransport.get());
+ ASSERT_NE(at0->mTransport.get(), at->mTransport.get());
}
}
TEST_P(JsepSessionTest, ParseRejectsBadMediaFormat)
{
AddTracks(*mSessionOff);
if (types.front() == SdpMediaSection::MediaType::kApplication) {
return;
@@ -4028,17 +4070,19 @@ TEST_F(JsepSessionTest, TestH264LevelAsy
// elsewhere
}
TEST_P(JsepSessionTest, TestRejectMline)
{
// We need to do this before adding tracks
types = BuildTypes(GetParam());
- switch (types.front()) {
+ SdpMediaSection::MediaType type = types.front();
+
+ switch (type) {
case SdpMediaSection::kAudio:
// Sabotage audio
EnsureNegotiationFailure(types.front(), "opus");
break;
case SdpMediaSection::kVideo:
// Sabotage video
EnsureNegotiationFailure(types.front(), "H264");
break;
@@ -4061,33 +4105,33 @@ TEST_P(JsepSessionTest, TestRejectMline)
UniquePtr<Sdp> outputSdp(Parse(answer));
ASSERT_TRUE(!!outputSdp);
ASSERT_NE(0U, outputSdp->GetMediaSectionCount());
SdpMediaSection* failed_section = nullptr;
for (size_t i = 0; i < outputSdp->GetMediaSectionCount(); ++i) {
- if (outputSdp->GetMediaSection(i).GetMediaType() == types.front()) {
+ if (outputSdp->GetMediaSection(i).GetMediaType() == type) {
failed_section = &outputSdp->GetMediaSection(i);
}
}
ASSERT_TRUE(failed_section) << "Failed type was entirely absent from SDP";
auto& failed_attrs = failed_section->GetAttributeList();
ASSERT_EQ(SdpDirectionAttribute::kInactive, failed_attrs.GetDirection());
ASSERT_EQ(0U, failed_section->GetPort());
mSessionAns->SetLocalDescription(kJsepSdpAnswer, answer);
mSessionOff->SetRemoteDescription(kJsepSdpAnswer, answer);
- size_t numRejected = std::count(types.begin(), types.end(), types.front());
+ size_t numRejected = std::count(types.begin(), types.end(), type);
size_t numAccepted = types.size() - numRejected;
- if (types.front() == SdpMediaSection::MediaType::kApplication) {
+ if (type == SdpMediaSection::MediaType::kApplication) {
ASSERT_TRUE(GetDatachannelTransceiver(*mSessionOff));
ASSERT_FALSE(
GetDatachannelTransceiver(*mSessionOff)->mRecvTrack.GetActive());
ASSERT_TRUE(GetDatachannelTransceiver(*mSessionAns));
ASSERT_FALSE(
GetDatachannelTransceiver(*mSessionAns)->mRecvTrack.GetActive());
} else {
ASSERT_EQ(types.size(), GetLocalTracks(*mSessionOff).size());