Change default sdp_semantics to kNotSpecified.

In preparation for switching the default from kPlanB to kUnifiedPlan,
which could cause subtle bugs for those not prepared for it, we change
the default to kNotSpecified. The only purpose of kNotSpecified is to
crash, forcing any dependencies to explicitly set their sdp_semantics
value.

Tests are updated to explicitly set sdp_semantics when necessary, and
where the test does not care we update to kUnifiedPlan.

If this change lands without getting reverted we can let it sit for a
few weeks, after which we should change the default to kUnifiedPlan and
delete kNotSpecified.

Bug: webrtc:11121
Change-Id: I19b669b0735d78e269e19eaae86c2d7d95a91141
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/242968
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35651}
diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h
index c367fae..d40d7a4 100644
--- a/api/peer_connection_interface.h
+++ b/api/peer_connection_interface.h
@@ -169,9 +169,16 @@
 };
 
 enum class SdpSemantics {
+  // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
   kPlanB_DEPRECATED,
   kPlanB [[deprecated]] = kPlanB_DEPRECATED,
-  kUnifiedPlan
+  kUnifiedPlan,
+  // The default SdpSemantics value is about to change to kUnifiedPlan. During a
+  // short transition period, kNotSpecified is used to ensure clients that don't
+  // set SdpSemantics are aware of the change by CHECK-crashing.
+  // TODO(https://crbug.com/webrtc/11121): When the default has changed to
+  // kUnifiedPlan, delete kNotSpecified.
+  kNotSpecified
 };
 
 class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface {
@@ -639,10 +646,17 @@
     // the same media type.
     //
     // For users who have to interwork with legacy WebRTC implementations,
-    // it is possible to specify kPlanB until the code is finally removed.
+    // it is possible to specify kPlanB until the code is finally removed
+    // (https://crbug.com/webrtc/13528).
     //
     // For all other users, specify kUnifiedPlan.
-    SdpSemantics sdp_semantics = SdpSemantics::kPlanB_DEPRECATED;
+    //
+    // The default SdpSemantics value is about to change to kUnifiedPlan. During
+    // a short transition period, kNotSpecified is used to ensure clients that
+    // don't set SdpSemantics are aware of the change by CHECK-crashing.
+    // TODO(https://crbug.com/webrtc/11121): When the default has changed to
+    // kUnifiedPlan, delete kNotSpecified.
+    SdpSemantics sdp_semantics = SdpSemantics::kNotSpecified;
 
     // TODO(bugs.webrtc.org/9891) - Move to crypto_options or remove.
     // Actively reset the SRTP parameters whenever the DTLS transports
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index bd90711..99828f8 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -418,6 +418,20 @@
     std::unique_ptr<Call> call,
     const PeerConnectionInterface::RTCConfiguration& configuration,
     PeerConnectionDependencies dependencies) {
+  // Prior to adding this CHECK, the default value was kPlanB. Because kPlanB is
+  // about to be deprecated in favor of the spec-compliant kUnifiedPlan, the
+  // default will soon change to kUnifiedPlan. This CHECK ensures that anybody
+  // implicitly relying on the default being kPlanB is made aware of the change.
+  // To avoid crashing, you can overwrite sdp_semantics to kPlanB for the old
+  // behavior, but you will need to migrate to kUnifiedPlan before kPlanB is
+  // removed.
+  // TODO(https://crbug.com/webrtc/11121): When the default is kUnifiedPlan,
+  // delete kNotSpecified.
+  // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
+  RTC_CHECK(configuration.sdp_semantics != SdpSemantics::kNotSpecified)
+      << "Please specify sdp_semantics. The default is about to change to "
+      << "kUnifiedPlan.";
+
   RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
       ParseIceConfig(configuration));
   if (!config_error.ok()) {
diff --git a/pc/peer_connection_factory_unittest.cc b/pc/peer_connection_factory_unittest.cc
index dd392c5..c12b563 100644
--- a/pc/peer_connection_factory_unittest.cc
+++ b/pc/peer_connection_factory_unittest.cc
@@ -190,6 +190,7 @@
 
   NullPeerConnectionObserver observer;
   webrtc::PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
 
   std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
       new FakeRTCCertificateGenerator());
@@ -269,6 +270,7 @@
 // configuration. Also verifies the URL's parsed correctly as expected.
 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServers) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
   webrtc::PeerConnectionInterface::IceServer ice_server;
   ice_server.uri = kStunIceServer;
   config.servers.push_back(ice_server);
@@ -304,6 +306,7 @@
 // configuration. Also verifies the list of URL's parsed correctly as expected.
 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServersUrls) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
   webrtc::PeerConnectionInterface::IceServer ice_server;
   ice_server.urls.push_back(kStunIceServer);
   ice_server.urls.push_back(kTurnIceServer);
@@ -333,6 +336,7 @@
 
 TEST_F(PeerConnectionFactoryTest, CreatePCUsingNoUsernameInUri) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
   webrtc::PeerConnectionInterface::IceServer ice_server;
   ice_server.uri = kStunIceServer;
   config.servers.push_back(ice_server);
@@ -357,6 +361,7 @@
 // has transport parameter in it.
 TEST_F(PeerConnectionFactoryTest, CreatePCUsingTurnUrlWithTransportParam) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
   webrtc::PeerConnectionInterface::IceServer ice_server;
   ice_server.uri = kTurnIceServerWithTransport;
   ice_server.username = kTurnUsername;
@@ -377,6 +382,7 @@
 
 TEST_F(PeerConnectionFactoryTest, CreatePCUsingSecureTurnUrl) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
   webrtc::PeerConnectionInterface::IceServer ice_server;
   ice_server.uri = kSecureTurnIceServer;
   ice_server.username = kTurnUsername;
@@ -414,6 +420,7 @@
 
 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIPLiteralAddress) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
   webrtc::PeerConnectionInterface::IceServer ice_server;
   ice_server.uri = kStunIceServerWithIPv4Address;
   config.servers.push_back(ice_server);
diff --git a/pc/peer_connection_histogram_unittest.cc b/pc/peer_connection_histogram_unittest.cc
index 8a1aa60..27bae85 100644
--- a/pc/peer_connection_histogram_unittest.cc
+++ b/pc/peer_connection_histogram_unittest.cc
@@ -243,8 +243,10 @@
   }
 
   WrapperPtr CreatePeerConnection() {
+    RTCConfiguration config;
+    config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
     return CreatePeerConnection(
-        RTCConfiguration(), PeerConnectionFactoryInterface::Options(), nullptr);
+        config, PeerConnectionFactoryInterface::Options(), nullptr);
   }
 
   WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
@@ -275,6 +277,7 @@
 
   WrapperPtr CreatePeerConnectionWithImmediateReport() {
     RTCConfiguration configuration;
+    configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
     configuration.report_usage_pattern_delay_ms = 0;
     return CreatePeerConnection(
         configuration, PeerConnectionFactoryInterface::Options(), nullptr);
@@ -287,7 +290,9 @@
 
     auto port_allocator =
         std::make_unique<cricket::BasicPortAllocator>(fake_network);
-    return CreatePeerConnection(RTCConfiguration(),
+    RTCConfiguration config;
+    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
+    return CreatePeerConnection(config,
                                 PeerConnectionFactoryInterface::Options(),
                                 std::move(port_allocator));
   }
@@ -300,7 +305,9 @@
     auto port_allocator =
         std::make_unique<cricket::BasicPortAllocator>(fake_network);
 
-    return CreatePeerConnection(RTCConfiguration(),
+    RTCConfiguration config;
+    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
+    return CreatePeerConnection(config,
                                 PeerConnectionFactoryInterface::Options(),
                                 std::move(port_allocator));
   }
@@ -420,6 +427,7 @@
 // candidate.
 TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
 
   // Enable hostname candidates with mDNS names.
   auto caller = CreatePeerConnectionWithMdns(config);
@@ -461,6 +469,7 @@
 // candidate.
 TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
 
   // Enable hostname candidates with mDNS names.
   auto caller = CreatePeerConnection(config);
@@ -526,6 +535,7 @@
 
 TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
   RTCConfiguration configuration;
+  configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
   PeerConnection::IceServer server;
   server.urls = {"stun:dummy.stun.server"};
   configuration.servers.push_back(server);
@@ -546,6 +556,7 @@
 
 TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
   RTCConfiguration configuration;
+  configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
   PeerConnection::IceServer server;
   server.urls = {"stun:dummy.stun.server"};
   configuration.servers.push_back(server);
@@ -641,7 +652,9 @@
   // signaled and we expect a connection with prflx remote candidates at the
   // caller side.
   auto caller = CreatePeerConnectionWithPrivateIpv6LocalAddresses();
-  auto callee = CreatePeerConnectionWithMdns(RTCConfiguration());
+  RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
+  auto callee = CreatePeerConnectionWithMdns(config);
   caller->CreateDataChannel("test_channel");
   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
   // Wait until the gathering completes so that the session description would
diff --git a/pc/peer_connection_ice_unittest.cc b/pc/peer_connection_ice_unittest.cc
index 112d8df..49a79a2 100644
--- a/pc/peer_connection_ice_unittest.cc
+++ b/pc/peer_connection_ice_unittest.cc
@@ -844,6 +844,7 @@
   const SocketAddress kLocalAddress("1.1.1.1", 0);
 
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.continual_gathering_policy =
       PeerConnectionInterface::GATHER_CONTINUALLY;
   auto caller = CreatePeerConnectionWithAudioVideo(config);
@@ -866,6 +867,7 @@
   const SocketAddress kLocalAddress("1.1.1.1", 0);
 
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.continual_gathering_policy =
       PeerConnectionInterface::GATHER_CONTINUALLY;
   auto caller = CreatePeerConnectionWithAudioVideo(config);
@@ -892,6 +894,7 @@
   const SocketAddress kLocalAddress("1.1.1.1", 0);
 
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
   auto caller = CreatePeerConnectionWithAudioVideo(config);
   caller->network()->AddInterface(kLocalAddress);
@@ -1392,6 +1395,7 @@
 
 TEST_F(PeerConnectionIceConfigTest, SetStunCandidateKeepaliveInterval) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.stun_candidate_keepalive_interval = 123;
   config.ice_candidate_pool_size = 1;
   CreatePeerConnection(config);
@@ -1408,6 +1412,7 @@
 
 TEST_F(PeerConnectionIceConfigTest, SetStableWritableConnectionInterval) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.stable_writable_connection_ping_interval_ms = 3500;
   CreatePeerConnection(config);
   EXPECT_TRUE(pc_->SetConfiguration(config).ok());
@@ -1418,6 +1423,7 @@
 TEST_F(PeerConnectionIceConfigTest,
        SetStableWritableConnectionInterval_FailsValidation) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   CreatePeerConnection(config);
   ASSERT_TRUE(pc_->SetConfiguration(config).ok());
   config.stable_writable_connection_ping_interval_ms = 5000;
@@ -1428,6 +1434,7 @@
 TEST_F(PeerConnectionIceConfigTest,
        SetStableWritableConnectionInterval_DefaultValue_FailsValidation) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   CreatePeerConnection(config);
   ASSERT_TRUE(pc_->SetConfiguration(config).ok());
   config.ice_check_interval_strong_connectivity = 2500;
@@ -1438,6 +1445,7 @@
 
 TEST_P(PeerConnectionIceTest, IceCredentialsCreateOffer) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.ice_candidate_pool_size = 1;
   auto pc = CreatePeerConnectionWithAudioVideo(config);
   ASSERT_NE(pc->port_allocator_, nullptr);
@@ -1455,6 +1463,7 @@
 
 TEST_P(PeerConnectionIceTest, IceCredentialsCreateAnswer) {
   RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   config.ice_candidate_pool_size = 1;
   auto pc = CreatePeerConnectionWithAudioVideo(config);
   ASSERT_NE(pc->port_allocator_, nullptr);
diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc
index 3aaae64..44f135f 100644
--- a/pc/peer_connection_interface_unittest.cc
+++ b/pc/peer_connection_interface_unittest.cc
@@ -1332,6 +1332,7 @@
 // in the RTCConfiguration.
 TEST_P(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   PeerConnectionInterface::IceServer server;
   server.uri = kStunAddressOnly;
   config.servers.push_back(server);
@@ -1375,6 +1376,7 @@
   // Create RTCConfiguration with some network-related fields relevant to
   // PortAllocator populated.
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.disable_ipv6_on_wifi = true;
   config.max_ipv6_networks = 10;
   config.tcp_candidate_policy =
@@ -1415,6 +1417,7 @@
 // constructed with, before SetConfiguration is called.
 TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.type = PeerConnectionInterface::kRelay;
   CreatePeerConnection(config);
 
@@ -1427,6 +1430,7 @@
 // SetConfiguration.
 TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
   PeerConnectionInterface::RTCConfiguration starting_config;
+  starting_config.sdp_semantics = sdp_semantics_;
   starting_config.bundle_policy =
       webrtc::PeerConnection::kBundlePolicyMaxBundle;
   CreatePeerConnection(starting_config);
@@ -3009,6 +3013,7 @@
 // changing, the next offer causes an ICE restart.
 TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingIceRestart) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.type = PeerConnectionInterface::kRelay;
   CreatePeerConnection(config);
   config = pc_->GetConfiguration();
@@ -3043,6 +3048,7 @@
 // changing, the next offer does *not* cause an ICE restart.
 TEST_P(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRestart) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.type = PeerConnectionInterface::kRelay;
   CreatePeerConnection(config);
   config = pc_->GetConfiguration();
@@ -3077,6 +3083,7 @@
 //    that was already restarted.
 TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.type = PeerConnectionInterface::kRelay;
   CreatePeerConnection(config);
   config = pc_->GetConfiguration();
@@ -3237,6 +3244,7 @@
 // RTCConfiguration.
 TEST_P(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.enable_ice_renomination = false;
   CreatePeerConnection(config);
   AddAudioTrack("foo");
@@ -3253,6 +3261,7 @@
 // if it's enabled in the PC's RTCConfiguration.
 TEST_P(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.enable_ice_renomination = true;
   CreatePeerConnection(config);
   AddAudioTrack("foo");
@@ -3337,6 +3346,7 @@
        DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy) {
 #endif  // WEBRTC_HAVE_SCTP
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = sdp_semantics_;
   config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
   CreatePeerConnection(config);
 
@@ -3676,6 +3686,7 @@
 // This sanity check validates the test infrastructure itself.
 TEST_F(PeerConnectionMediaConfigTest, TestCreateAndClose) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   rtc::scoped_refptr<PeerConnectionInterface> pc(
       pcf_->CreatePeerConnection(config, nullptr, nullptr, &observer_));
   EXPECT_TRUE(pc.get());
@@ -3688,6 +3699,7 @@
 // default RTCConfiguration.
 TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
 
   const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
 
@@ -3702,6 +3714,7 @@
 // propagated from RTCConfiguration to the PeerConnection.
 TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
 
   config.set_prerenderer_smoothing(false);
   const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
@@ -3713,6 +3726,7 @@
 // propagated from RTCConfiguration to the PeerConnection.
 TEST_F(PeerConnectionMediaConfigTest, TestEnableExperimentCpuLoadEstimator) {
   PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
 
   config.set_experiment_cpu_load_estimator(true);
   const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
diff --git a/pc/peer_connection_rampup_tests.cc b/pc/peer_connection_rampup_tests.cc
index d845b57..692ca9d 100644
--- a/pc/peer_connection_rampup_tests.cc
+++ b/pc/peer_connection_rampup_tests.cc
@@ -344,9 +344,11 @@
   ice_server.username = "test";
   ice_server.password = "test";
   PeerConnectionInterface::RTCConfiguration client_1_config;
+  client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_1_config.servers.push_back(ice_server);
   client_1_config.type = PeerConnectionInterface::kRelay;
   PeerConnectionInterface::RTCConfiguration client_2_config;
+  client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_2_config.servers.push_back(ice_server);
   client_2_config.type = PeerConnectionInterface::kRelay;
   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
@@ -365,9 +367,11 @@
   ice_server.username = "test";
   ice_server.password = "test";
   PeerConnectionInterface::RTCConfiguration client_1_config;
+  client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_1_config.servers.push_back(ice_server);
   client_1_config.type = PeerConnectionInterface::kRelay;
   PeerConnectionInterface::RTCConfiguration client_2_config;
+  client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_2_config.servers.push_back(ice_server);
   client_2_config.type = PeerConnectionInterface::kRelay;
   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
@@ -386,9 +390,11 @@
   ice_server.username = "test";
   ice_server.password = "test";
   PeerConnectionInterface::RTCConfiguration client_1_config;
+  client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_1_config.servers.push_back(ice_server);
   client_1_config.type = PeerConnectionInterface::kRelay;
   PeerConnectionInterface::RTCConfiguration client_2_config;
+  client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_2_config.servers.push_back(ice_server);
   client_2_config.type = PeerConnectionInterface::kRelay;
 
@@ -400,9 +406,11 @@
 
 TEST_F(PeerConnectionRampUpTest, Bwe_After_UDPPeerToPeer) {
   PeerConnectionInterface::RTCConfiguration client_1_config;
+  client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_1_config.tcp_candidate_policy =
       PeerConnection::kTcpCandidatePolicyDisabled;
   PeerConnectionInterface::RTCConfiguration client_2_config;
+  client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
   client_2_config.tcp_candidate_policy =
       PeerConnection::kTcpCandidatePolicyDisabled;
   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
@@ -413,9 +421,9 @@
 
 TEST_F(PeerConnectionRampUpTest, Bwe_After_TCPPeerToPeer) {
   firewall_socket_server()->set_udp_sockets_enabled(false);
-  ASSERT_TRUE(CreatePeerConnectionWrappers(
-      PeerConnectionInterface::RTCConfiguration(),
-      PeerConnectionInterface::RTCConfiguration()));
+  PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
+  ASSERT_TRUE(CreatePeerConnectionWrappers(config, config));
 
   SetupOneWayCall();
   RunTest("tcp_peer_to_peer");
diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc
index ca0df26..ad53349 100644
--- a/pc/rtc_stats_integrationtest.cc
+++ b/pc/rtc_stats_integrationtest.cc
@@ -123,6 +123,7 @@
   void StartCall() {
     // Create PeerConnections and "connect" sigslots
     PeerConnectionInterface::RTCConfiguration config;
+    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
     PeerConnectionInterface::IceServer ice_server;
     ice_server.uri = "stun:1.1.1.1:3478";
     config.servers.push_back(ice_server);
diff --git a/pc/test/integration_test_helpers.h b/pc/test/integration_test_helpers.h
index fb59092..dd93542 100644
--- a/pc/test/integration_test_helpers.h
+++ b/pc/test/integration_test_helpers.h
@@ -774,6 +774,7 @@
       const PeerConnectionInterface::RTCConfiguration* config,
       webrtc::PeerConnectionDependencies dependencies) {
     PeerConnectionInterface::RTCConfiguration modified_config;
+    modified_config.sdp_semantics = sdp_semantics_;
     // If `config` is null, this will result in a default configuration being
     // used.
     if (config) {
diff --git a/sdk/objc/api/peerconnection/RTCConfiguration.mm b/sdk/objc/api/peerconnection/RTCConfiguration.mm
index 2b6e4ec..0885e96 100644
--- a/sdk/objc/api/peerconnection/RTCConfiguration.mm
+++ b/sdk/objc/api/peerconnection/RTCConfiguration.mm
@@ -17,6 +17,7 @@
 #import "RTCIceServer+Private.h"
 #import "base/RTCLogging.h"
 
+#include "rtc_base/checks.h"
 #include "rtc_base/rtc_certificate_generator.h"
 #include "rtc_base/ssl_identity.h"
 
@@ -67,6 +68,7 @@
 - (instancetype)init {
   // Copy defaults.
   webrtc::PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kPlanB_DEPRECATED;
   return [self initWithNativeConfiguration:config];
 }
 
@@ -532,6 +534,9 @@
       return RTCSdpSemanticsPlanB;
     case webrtc::SdpSemantics::kUnifiedPlan:
       return RTCSdpSemanticsUnifiedPlan;
+    case webrtc::SdpSemantics::kNotSpecified:
+      RTC_DCHECK_NOTREACHED();
+      return RTCSdpSemanticsUnifiedPlan;
   }
 }