Add SDP munging detection for transceiver direction

Changing direction of transceiver is unexpected in most cases.

Bug: webrtc:40567530
Change-Id: I7b8c4132ac04bf20649ce6152d4289de23a7a60c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/387180
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@meta.com>
Reviewed-by: Philipp Hancke <phancke@meta.com>
Cr-Commit-Position: refs/heads/main@{#44503}
diff --git a/AUTHORS b/AUTHORS
index 0599f49..62ae772 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -122,6 +122,7 @@
 Robert Mader <robert.mader@posteo.de>
 Robert Nagy <robert.nagy@gmail.com>
 Ryan Yoakum <ryoakum@skobalt.com>
+Saming Lin <santoin351@gmail.com>
 Samuel Attard <samuel.r.attard@gmail.com>
 Sarah Thompson <sarah@telergy.com>
 Satender Saroha <ssaroha@yahoo.com>
diff --git a/api/uma_metrics.h b/api/uma_metrics.h
index 1525f08..980cb88 100644
--- a/api/uma_metrics.h
+++ b/api/uma_metrics.h
@@ -195,6 +195,7 @@
   kPayloadTypes = 26,
   kSsrcs = 27,
   kIceOptionsRenomination = 28,
+  kDirection = 29,
   // RTP header extension munging.
   kRtpHeaderExtensionRemoved = 40,
   kRtpHeaderExtensionAdded = 41,
diff --git a/pc/sdp_munging_detector.cc b/pc/sdp_munging_detector.cc
index 2497a30..e54c228 100644
--- a/pc/sdp_munging_detector.cc
+++ b/pc/sdp_munging_detector.cc
@@ -444,6 +444,12 @@
       }
     }
 
+    if (last_created_media_description->direction() !=
+        media_description_to_set->direction()) {
+      RTC_LOG(LS_WARNING) << "SDP munging: transceiver direction modified.";
+      return SdpMungingType::kDirection;
+    }
+
     // Validate media streams.
     if (last_created_media_description->streams().size() !=
         media_description_to_set->streams().size()) {
diff --git a/pc/sdp_offer_answer_unittest.cc b/pc/sdp_offer_answer_unittest.cc
index 16c3c22..20567b5 100644
--- a/pc/sdp_offer_answer_unittest.cc
+++ b/pc/sdp_offer_answer_unittest.cc
@@ -2111,6 +2111,28 @@
       ElementsAre(Pair(SdpMungingType::kNumberOfContents, 1)));
 }
 
+TEST_F(SdpOfferAnswerMungingTest, TransceiverDirection) {
+  auto pc = CreatePeerConnection();
+  pc->AddAudioTrack("audio_track", {});
+
+  auto offer = pc->CreateOffer();
+  auto& contents = offer->description()->contents();
+  ASSERT_EQ(contents.size(), 1u);
+  auto* media_description = contents[0].media_description();
+  ASSERT_TRUE(media_description);
+  auto direction = media_description->direction();
+  if (direction == RtpTransceiverDirection::kInactive) {
+    media_description->set_direction(RtpTransceiverDirection::kSendRecv);
+  } else {
+    media_description->set_direction(RtpTransceiverDirection::kInactive);
+  }
+  RTCError error;
+  EXPECT_TRUE(pc->SetLocalDescription(std::move(offer), &error));
+  EXPECT_THAT(
+      metrics::Samples("WebRTC.PeerConnection.SdpMunging.Offer.Initial"),
+      ElementsAre(Pair(SdpMungingType::kDirection, 1)));
+}
+
 TEST_F(SdpOfferAnswerMungingTest, Mid) {
   auto pc = CreatePeerConnection();
   pc->AddAudioTrack("audio_track", {});