Replace string type with SdpType enum

This moves all WebRTC internal code from using
SessionDescriptionInterface::type() which returns a string and
from using CreateSessionDescription with a string type parameter.

Bug: webrtc:8613
Change-Id: I1cdd93dc4b26dec157e22476fdac569d5da2810a
Reviewed-on: https://webrtc-review.googlesource.com/29500
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Zhi Huang <zhihuang@webrtc.org>
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21147}
diff --git a/examples/peerconnection/client/conductor.cc b/examples/peerconnection/client/conductor.cc
index 7394137..f15e221 100644
--- a/examples/peerconnection/client/conductor.cc
+++ b/examples/peerconnection/client/conductor.cc
@@ -24,6 +24,8 @@
 #include "rtc_base/json.h"
 #include "rtc_base/logging.h"
 
+using webrtc::SdpType;
+
 // Names used for a IceCandidate JSON object.
 const char kCandidateSdpMidName[] = "sdpMid";
 const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
@@ -258,12 +260,13 @@
     RTC_LOG(WARNING) << "Received unknown message. " << message;
     return;
   }
-  std::string type;
+  std::string type_str;
   std::string json_object;
 
-  rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName, &type);
-  if (!type.empty()) {
-    if (type == "offer-loopback") {
+  rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName,
+                               &type_str);
+  if (!type_str.empty()) {
+    if (type_str == "offer-loopback") {
       // This is a loopback call.
       // Recreate the peerconnection with DTLS disabled.
       if (!ReinitializePeerConnectionForLoopback()) {
@@ -273,7 +276,12 @@
       }
       return;
     }
-
+    rtc::Optional<SdpType> type_maybe = webrtc::SdpTypeFromString(type_str);
+    if (!type_maybe) {
+      RTC_LOG(LS_ERROR) << "Unknown SDP type: " << type_str;
+      return;
+    }
+    SdpType type = *type_maybe;
     std::string sdp;
     if (!rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName,
                                       &sdp)) {
@@ -281,8 +289,8 @@
       return;
     }
     webrtc::SdpParseError error;
-    webrtc::SessionDescriptionInterface* session_description(
-        webrtc::CreateSessionDescription(type, sdp, &error));
+    std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
+        webrtc::CreateSessionDescription(type, sdp, &error);
     if (!session_description) {
       RTC_LOG(WARNING) << "Can't parse received session description message. "
                        << "SdpParseError was: " << error.description;
@@ -290,9 +298,9 @@
     }
     RTC_LOG(INFO) << " Received session description :" << message;
     peer_connection_->SetRemoteDescription(
-        DummySetSessionDescriptionObserver::Create(), session_description);
-    if (session_description->type() ==
-        webrtc::SessionDescriptionInterface::kOffer) {
+        DummySetSessionDescriptionObserver::Create(),
+        session_description.release());
+    if (type == SdpType::kOffer) {
       peer_connection_->CreateAnswer(this, NULL);
     }
     return;
@@ -525,16 +533,18 @@
   // For loopback test. To save some connecting delay.
   if (loopback_) {
     // Replace message type from "offer" to "answer"
-    webrtc::SessionDescriptionInterface* session_description(
-        webrtc::CreateSessionDescription("answer", sdp, nullptr));
+    std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
+        webrtc::CreateSessionDescription(SdpType::kAnswer, sdp);
     peer_connection_->SetRemoteDescription(
-        DummySetSessionDescriptionObserver::Create(), session_description);
+        DummySetSessionDescriptionObserver::Create(),
+        session_description.release());
     return;
   }
 
   Json::StyledWriter writer;
   Json::Value jmessage;
-  jmessage[kSessionDescriptionTypeName] = desc->type();
+  jmessage[kSessionDescriptionTypeName] =
+      webrtc::SdpTypeToString(desc->GetType());
   jmessage[kSessionDescriptionSdpName] = sdp;
   SendMessage(writer.write(jmessage));
 }
diff --git a/pc/jsepsessiondescription_unittest.cc b/pc/jsepsessiondescription_unittest.cc
index 27b2cf1..946d39d 100644
--- a/pc/jsepsessiondescription_unittest.cc
+++ b/pc/jsepsessiondescription_unittest.cc
@@ -15,11 +15,12 @@
 #include "api/jsepicecandidate.h"
 #include "api/jsepsessiondescription.h"
 #include "api/webrtcsdp.h"
-#include "p2p/base/port.h"
 #include "p2p/base/p2pconstants.h"
+#include "p2p/base/port.h"
 #include "p2p/base/sessiondescription.h"
 #include "pc/mediasession.h"
 #include "rtc_base/gunit.h"
+#include "rtc_base/ptr_util.h"
 #include "rtc_base/stringencode.h"
 
 using ::testing::Values;
@@ -85,7 +86,7 @@
         rtc::ToString(rtc::CreateRandomId64());
     const std::string session_version =
         rtc::ToString(rtc::CreateRandomId());
-    jsep_desc_.reset(new JsepSessionDescription("dummy"));
+    jsep_desc_ = rtc::MakeUnique<JsepSessionDescription>(SdpType::kOffer);
     ASSERT_TRUE(jsep_desc_->Initialize(CreateCricketSessionDescription(),
         session_id, session_version));
   }
@@ -97,10 +98,11 @@
     return sdp;
   }
 
-  SessionDescriptionInterface* DeSerialize(const std::string& sdp) {
-    JsepSessionDescription* desc(new JsepSessionDescription("dummy"));
-    EXPECT_TRUE(webrtc::SdpDeserialize(sdp, desc, nullptr));
-    return desc;
+  std::unique_ptr<SessionDescriptionInterface> DeSerialize(
+      const std::string& sdp) {
+    auto jsep_desc = rtc::MakeUnique<JsepSessionDescription>(SdpType::kOffer);
+    EXPECT_TRUE(webrtc::SdpDeserialize(sdp, jsep_desc.get(), nullptr));
+    return std::move(jsep_desc);
   }
 
   cricket::Candidate candidate_;
@@ -208,8 +210,7 @@
 TEST_F(JsepSessionDescriptionTest, SerializeDeserialize) {
   std::string sdp = Serialize(jsep_desc_.get());
 
-  std::unique_ptr<SessionDescriptionInterface> parsed_jsep_desc(
-      DeSerialize(sdp));
+  auto parsed_jsep_desc = DeSerialize(sdp);
   EXPECT_EQ(2u, parsed_jsep_desc->number_of_mediasections());
 
   std::string parsed_sdp = Serialize(parsed_jsep_desc.get());
@@ -227,8 +228,7 @@
   std::string sdp_with_candidate = Serialize(jsep_desc_.get());
   EXPECT_NE(sdp, sdp_with_candidate);
 
-  std::unique_ptr<SessionDescriptionInterface> parsed_jsep_desc(
-      DeSerialize(sdp_with_candidate));
+  auto parsed_jsep_desc = DeSerialize(sdp_with_candidate);
   std::string parsed_sdp_with_candidate = Serialize(parsed_jsep_desc.get());
 
   EXPECT_EQ(sdp_with_candidate, parsed_sdp_with_candidate);
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index fcc3af9..4e65c31 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -35,6 +35,7 @@
 #include "pc/rtpreceiver.h"
 #include "pc/rtpsender.h"
 #include "pc/sctputils.h"
+#include "pc/sdputils.h"
 #include "pc/streamcollection.h"
 #include "pc/videocapturertracksource.h"
 #include "pc/videotrack.h"
@@ -1439,7 +1440,7 @@
   }
 
   if (remote_description() &&
-      remote_description()->type() != SessionDescriptionInterface::kOffer) {
+      remote_description()->GetType() != SdpType::kOffer) {
     std::string error = "CreateAnswer called without remote offer.";
     RTC_LOG(LS_ERROR) << error;
     PostCreateSessionDescriptionFailure(observer, error);
@@ -1467,14 +1468,16 @@
     return;
   }
 
-  std::string desc_type = desc->type();
+  SdpType type = desc->GetType();
 
   RTCError error = ApplyLocalDescription(rtc::WrapUnique(desc));
   // |desc| may be destroyed at this point.
 
   if (!error.ok()) {
-    std::string error_message =
-        "Failed to set local " + desc_type + " sdp: " + error.message();
+    std::ostringstream oss;
+    oss << "Failed to set local " << SdpTypeToString(type)
+        << " sdp: " << error.message();
+    std::string error_message = oss.str();
     RTC_LOG(LS_ERROR) << error_message << " (" << error.type() << ")";
     PostSetSessionDescriptionFailure(observer, std::move(error_message));
     return;
@@ -1493,7 +1496,7 @@
   // before signaling that SetLocalDescription completed.
   transport_controller_->MaybeStartGathering();
 
-  if (local_description()->type() == SessionDescriptionInterface::kAnswer) {
+  if (local_description()->GetType() == SdpType::kAnswer) {
     // TODO(deadbeef): We already had to hop to the network thread for
     // MaybeStartGathering...
     network_thread()->Invoke<void>(
@@ -1640,21 +1643,23 @@
     return;
   }
 
-  std::string desc_type = desc->type();
+  const SdpType type = desc->GetType();
 
   RTCError error = ApplyRemoteDescription(std::move(desc));
   // |desc| may be destroyed at this point.
 
   if (!error.ok()) {
-    std::string error_message =
-        "Failed to set remote " + desc_type + " sdp: " + error.message();
+    std::ostringstream oss;
+    oss << "Failed to set remote " << SdpTypeToString(type)
+        << " sdp: " << error.message();
+    std::string error_message = oss.str();
     RTC_LOG(LS_ERROR) << error_message << " (" << error.type() << ")";
     observer->OnSetRemoteDescriptionComplete(
         RTCError(error.type(), std::move(error_message)));
     return;
   }
 
-  if (remote_description()->type() == SessionDescriptionInterface::kAnswer) {
+  if (remote_description()->GetType() == SdpType::kAnswer) {
     // TODO(deadbeef): We already had to hop to the network thread for
     // MaybeStartGathering...
     network_thread()->Invoke<void>(
@@ -1766,7 +1771,7 @@
   // transport and expose a new checking() member from transport that can be
   // read to determine the current checking state. The existing SignalConnecting
   // actually means "gathering candidates", so cannot be be used here.
-  if (remote_description()->type() != SessionDescriptionInterface::kOffer &&
+  if (remote_description()->GetType() != SdpType::kOffer &&
       ice_connection_state() == PeerConnectionInterface::kIceConnectionNew) {
     SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
   }
@@ -2675,8 +2680,7 @@
   rtc::Optional<size_t> data_index;
   if (remote_description()) {
     // The pending remote description should be an offer.
-    RTC_DCHECK(remote_description()->type() ==
-               SessionDescriptionInterface::kOffer);
+    RTC_DCHECK(remote_description()->GetType() == SdpType::kOffer);
     // Generate m= sections that match those in the offer.
     // Note that mediasession.cc will handle intersection our preferred
     // direction with the offered direction.
diff --git a/pc/peerconnection_integrationtest.cc b/pc/peerconnection_integrationtest.cc
index 8ce692e..d301d98 100644
--- a/pc/peerconnection_integrationtest.cc
+++ b/pc/peerconnection_integrationtest.cc
@@ -82,6 +82,7 @@
 using webrtc::PeerConnectionFactory;
 using webrtc::PeerConnectionProxy;
 using webrtc::RtpReceiverInterface;
+using webrtc::SdpType;
 using webrtc::SessionDescriptionInterface;
 using webrtc::StreamCollectionInterface;
 
@@ -138,8 +139,7 @@
 
 class SignalingMessageReceiver {
  public:
-  virtual void ReceiveSdpMessage(const std::string& type,
-                                 const std::string& msg) = 0;
+  virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
   virtual void ReceiveIceMessage(const std::string& sdp_mid,
                                  int sdp_mline_index,
                                  const std::string& msg) = 0;
@@ -681,8 +681,8 @@
 
   void HandleIncomingOffer(const std::string& msg) {
     RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
-    std::unique_ptr<SessionDescriptionInterface> desc(
-        webrtc::CreateSessionDescription("offer", msg, nullptr));
+    std::unique_ptr<SessionDescriptionInterface> desc =
+        webrtc::CreateSessionDescription(SdpType::kOffer, msg);
     if (received_sdp_munger_) {
       received_sdp_munger_(desc->description());
     }
@@ -698,8 +698,8 @@
 
   void HandleIncomingAnswer(const std::string& msg) {
     RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
-    std::unique_ptr<SessionDescriptionInterface> desc(
-        webrtc::CreateSessionDescription("answer", msg, nullptr));
+    std::unique_ptr<SessionDescriptionInterface> desc =
+        webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
     if (received_sdp_munger_) {
       received_sdp_munger_(desc->description());
     }
@@ -748,7 +748,7 @@
     rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
         new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
     RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
-    std::string type = desc->type();
+    SdpType type = desc->GetType();
     std::string sdp;
     EXPECT_TRUE(desc->ToString(&sdp));
     pc()->SetLocalDescription(observer, desc.release());
@@ -770,7 +770,7 @@
 
   // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
   // default).
-  void SendSdpMessage(const std::string& type, const std::string& msg) {
+  void SendSdpMessage(SdpType type, const std::string& msg) {
     if (signaling_delay_ms_ == 0) {
       RelaySdpMessageIfReceiverExists(type, msg);
     } else {
@@ -782,8 +782,7 @@
     }
   }
 
-  void RelaySdpMessageIfReceiverExists(const std::string& type,
-                                       const std::string& msg) {
+  void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
     if (signaling_message_receiver_) {
       signaling_message_receiver_->ReceiveSdpMessage(type, msg);
     }
@@ -815,9 +814,8 @@
   }
 
   // SignalingMessageReceiver callbacks.
-  void ReceiveSdpMessage(const std::string& type,
-                         const std::string& msg) override {
-    if (type == webrtc::SessionDescriptionInterface::kOffer) {
+  void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
+    if (type == SdpType::kOffer) {
       HandleIncomingOffer(msg);
     } else {
       HandleIncomingAnswer(msg);
diff --git a/pc/peerconnection_signaling_unittest.cc b/pc/peerconnection_signaling_unittest.cc
index 0d9bf62..48de0ab 100644
--- a/pc/peerconnection_signaling_unittest.cc
+++ b/pc/peerconnection_signaling_unittest.cc
@@ -173,8 +173,8 @@
         auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
         wrapper->SetRemoteDescription(caller->CreateOffer());
         auto answer = wrapper->CreateAnswer();
-        wrapper->SetLocalDescription(CloneSessionDescriptionAsType(
-            answer.get(), SessionDescriptionInterface::kPrAnswer));
+        wrapper->SetLocalDescription(
+            CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
         break;
       }
       case SignalingState::kHaveRemoteOffer: {
@@ -186,8 +186,8 @@
         auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
         callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
         auto answer = callee->CreateAnswer();
-        wrapper->SetRemoteDescription(CloneSessionDescriptionAsType(
-            answer.get(), SessionDescriptionInterface::kPrAnswer));
+        wrapper->SetRemoteDescription(
+            CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
         break;
       }
       case SignalingState::kClosed: {
diff --git a/pc/peerconnectioninterface_unittest.cc b/pc/peerconnectioninterface_unittest.cc
index abe5666..c1168a0 100644
--- a/pc/peerconnectioninterface_unittest.cc
+++ b/pc/peerconnectioninterface_unittest.cc
@@ -352,6 +352,7 @@
 using webrtc::RtpSenderInterface;
 using webrtc::RtpTransceiverDirection;
 using webrtc::SdpParseError;
+using webrtc::SdpType;
 using webrtc::SessionDescriptionInterface;
 using webrtc::StreamCollection;
 using webrtc::StreamCollectionInterface;
@@ -873,16 +874,14 @@
     std::string sdp;
     EXPECT_TRUE(offer->ToString(&sdp));
     std::unique_ptr<SessionDescriptionInterface> remote_offer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
     EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
   }
 
   void CreateAndSetRemoteOffer(const std::string& sdp) {
     std::unique_ptr<SessionDescriptionInterface> remote_offer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
     EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
   }
@@ -901,8 +900,7 @@
     std::string sdp;
     EXPECT_TRUE(answer->ToString(&sdp));
     std::unique_ptr<SessionDescriptionInterface> new_answer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
     EXPECT_TRUE(DoSetLocalDescription(std::move(new_answer)));
     EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
   }
@@ -914,8 +912,7 @@
     std::string sdp;
     EXPECT_TRUE(answer->ToString(&sdp));
     std::unique_ptr<SessionDescriptionInterface> pr_answer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
     EXPECT_TRUE(DoSetLocalDescription(std::move(pr_answer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
   }
@@ -940,8 +937,7 @@
     std::string sdp;
     EXPECT_TRUE(offer->ToString(&sdp));
     std::unique_ptr<SessionDescriptionInterface> new_offer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
 
     EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
@@ -951,8 +947,7 @@
 
   void CreateAnswerAsRemoteDescription(const std::string& sdp) {
     std::unique_ptr<SessionDescriptionInterface> answer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
     ASSERT_TRUE(answer);
     EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
     EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
@@ -960,14 +955,12 @@
 
   void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
     std::unique_ptr<SessionDescriptionInterface> pr_answer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
     ASSERT_TRUE(pr_answer);
     EXPECT_TRUE(DoSetRemoteDescription(std::move(pr_answer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
     std::unique_ptr<SessionDescriptionInterface> answer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
     ASSERT_TRUE(answer);
     EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
     EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
@@ -1034,8 +1027,7 @@
     }
 
     return std::unique_ptr<SessionDescriptionInterface>(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                         sdp_ms1, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kOffer, sdp_ms1));
   }
 
   void AddAudioTrack(const std::string& track_id,
@@ -1098,8 +1090,7 @@
     std::string sdp;
     EXPECT_TRUE((*desc)->ToString(&sdp));
     std::unique_ptr<SessionDescriptionInterface> remote_offer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
     EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
   }
@@ -1112,8 +1103,7 @@
     std::string sdp;
     EXPECT_TRUE((*desc)->ToString(&sdp));
     std::unique_ptr<SessionDescriptionInterface> new_offer(
-        webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                         sdp, nullptr));
+        webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
 
     EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
     EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
@@ -2098,8 +2088,7 @@
   std::string sdp;
   EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
   std::unique_ptr<SessionDescriptionInterface> answer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                       sdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
   ASSERT_TRUE(answer);
   cricket::ContentInfo* data_info =
       answer->description()->GetContentByName("data");
@@ -2119,7 +2108,7 @@
   CreatePeerConnection(&constraints);
   AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
   std::unique_ptr<SessionDescriptionInterface> desc(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
+      webrtc::CreateSessionDescription(SdpType::kOffer,
                                        webrtc::kFireFoxSdpOffer, nullptr));
   EXPECT_TRUE(DoSetSessionDescription(std::move(desc), false));
   CreateAnswerAsLocalDescription();
@@ -2158,8 +2147,8 @@
   EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
                  kTimeout);
   std::unique_ptr<SessionDescriptionInterface> desc(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                       kDtlsSdesFallbackSdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kOffer, kDtlsSdesFallbackSdp,
+                                       nullptr));
   EXPECT_FALSE(DoSetSessionDescription(std::move(desc), false));
 }
 
@@ -2172,14 +2161,13 @@
   CreateOfferAsLocalDescription();
 
   std::unique_ptr<SessionDescriptionInterface> answer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                       webrtc::kAudioSdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kAnswer, webrtc::kAudioSdp,
+                                       nullptr));
   EXPECT_TRUE(DoSetSessionDescription(std::move(answer), false));
 
   std::unique_ptr<SessionDescriptionInterface> updated_offer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                       webrtc::kAudioSdpWithUnsupportedCodecs,
-                                       nullptr));
+      webrtc::CreateSessionDescription(
+          SdpType::kOffer, webrtc::kAudioSdpWithUnsupportedCodecs, nullptr));
   EXPECT_TRUE(DoSetSessionDescription(std::move(updated_offer), false));
   CreateAnswerAsLocalDescription();
 }
@@ -2526,14 +2514,12 @@
   std::string sdp;
   ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
   std::unique_ptr<SessionDescriptionInterface> remote_offer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp,
-                                       nullptr));
+      webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
   EXPECT_FALSE(DoSetRemoteDescription(std::move(remote_offer)));
 
   ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
   std::unique_ptr<SessionDescriptionInterface> local_offer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp,
-                                       nullptr));
+      webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
   EXPECT_FALSE(DoSetLocalDescription(std::move(local_offer)));
 }
 
@@ -2680,8 +2666,8 @@
   remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
 
   std::unique_ptr<SessionDescriptionInterface> local_answer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                       kSdpStringWithStream1, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kAnswer, kSdpStringWithStream1,
+                                       nullptr));
   cricket::ContentInfo* video_info =
       local_answer->description()->GetContentByName("video");
   video_info->rejected = true;
@@ -2927,8 +2913,8 @@
   std::unique_ptr<SessionDescriptionInterface> offer;
   ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
   // Grab a copy of the offer before it gets passed into the PC.
-  std::unique_ptr<webrtc::JsepSessionDescription> modified_offer(
-      new webrtc::JsepSessionDescription(SessionDescriptionInterface::kOffer));
+  auto modified_offer =
+      rtc::MakeUnique<webrtc::JsepSessionDescription>(webrtc::SdpType::kOffer);
   modified_offer->Initialize(offer->description()->Copy(), offer->session_id(),
                              offer->session_version());
   EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
@@ -3110,8 +3096,8 @@
 
   // Do ICE restart for the first m= section, initiated by remote peer.
   std::unique_ptr<webrtc::SessionDescriptionInterface> remote_offer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
-                                       kSdpStringWithStream1, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kOffer, kSdpStringWithStream1,
+                                       nullptr));
   ASSERT_TRUE(remote_offer);
   remote_offer->description()->transport_infos()[0].description.ice_ufrag =
       "modified";
@@ -3157,8 +3143,7 @@
 
   // Set remote pranswer.
   std::unique_ptr<SessionDescriptionInterface> remote_pranswer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
-                                       sdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
   SessionDescriptionInterface* remote_pranswer_ptr = remote_pranswer.get();
   EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_pranswer)));
   EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
@@ -3168,8 +3153,7 @@
 
   // Set remote answer.
   std::unique_ptr<SessionDescriptionInterface> remote_answer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                       sdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
   SessionDescriptionInterface* remote_answer_ptr = remote_answer.get();
   EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_answer)));
   EXPECT_EQ(nullptr, pc_->pending_local_description());
@@ -3179,8 +3163,7 @@
 
   // Set remote offer.
   std::unique_ptr<SessionDescriptionInterface> remote_offer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp,
-                                       nullptr));
+      webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
   SessionDescriptionInterface* remote_offer_ptr = remote_offer.get();
   EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
   EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
@@ -3190,8 +3173,7 @@
 
   // Set local pranswer.
   std::unique_ptr<SessionDescriptionInterface> local_pranswer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
-                                       sdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
   SessionDescriptionInterface* local_pranswer_ptr = local_pranswer.get();
   EXPECT_TRUE(DoSetLocalDescription(std::move(local_pranswer)));
   EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
@@ -3201,8 +3183,7 @@
 
   // Set local answer.
   std::unique_ptr<SessionDescriptionInterface> local_answer(
-      webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
-                                       sdp, nullptr));
+      webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
   SessionDescriptionInterface* local_answer_ptr = local_answer.get();
   EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
   EXPECT_EQ(nullptr, pc_->pending_remote_description());
diff --git a/pc/sdputils.cc b/pc/sdputils.cc
index 9bcbc43..de77d63 100644
--- a/pc/sdputils.cc
+++ b/pc/sdputils.cc
@@ -21,16 +21,16 @@
 std::unique_ptr<SessionDescriptionInterface> CloneSessionDescription(
     const SessionDescriptionInterface* sdesc) {
   RTC_DCHECK(sdesc);
-  return CloneSessionDescriptionAsType(sdesc, sdesc->type());
+  return CloneSessionDescriptionAsType(sdesc, sdesc->GetType());
 }
 
 std::unique_ptr<SessionDescriptionInterface> CloneSessionDescriptionAsType(
     const SessionDescriptionInterface* sdesc,
-    const std::string& type) {
+    SdpType type) {
   RTC_DCHECK(sdesc);
   auto clone = rtc::MakeUnique<JsepSessionDescription>(type);
   clone->Initialize(sdesc->description()->Copy(), sdesc->session_id(),
-                              sdesc->session_version());
+                    sdesc->session_version());
   // As of writing, our version of GCC does not allow returning a unique_ptr of
   // a subclass as a unique_ptr of a base class. To get around this, we need to
   // std::move the return value.
diff --git a/pc/sdputils.h b/pc/sdputils.h
index 7444aa7..0b9fa35 100644
--- a/pc/sdputils.h
+++ b/pc/sdputils.h
@@ -27,7 +27,7 @@
 // Returns a copy of the given session description with the type changed.
 std::unique_ptr<SessionDescriptionInterface> CloneSessionDescriptionAsType(
     const SessionDescriptionInterface* sdesc,
-    const std::string& type);
+    SdpType type);
 
 // Function that takes a single session description content with its
 // corresponding transport and produces a boolean.
diff --git a/pc/test/peerconnectiontestwrapper.cc b/pc/test/peerconnectiontestwrapper.cc
index 6bed036..aa2f79e 100644
--- a/pc/test/peerconnectiontestwrapper.cc
+++ b/pc/test/peerconnectiontestwrapper.cc
@@ -12,19 +12,13 @@
 #include <utility>
 
 #include "p2p/base/fakeportallocator.h"
+#include "pc/sdputils.h"
 #include "pc/test/fakeperiodicvideocapturer.h"
 #include "pc/test/fakertccertificategenerator.h"
 #include "pc/test/mockpeerconnectionobservers.h"
 #include "pc/test/peerconnectiontestwrapper.h"
 #include "rtc_base/gunit.h"
 
-static const char kStreamLabelBase[] = "stream_label";
-static const char kVideoTrackLabelBase[] = "video_track";
-static const char kAudioTrackLabelBase[] = "audio_track";
-static const int kMaxWait = 10000;
-static const int kTestAudioFrameCount = 3;
-static const int kTestVideoFrameCount = 3;
-
 using webrtc::FakeConstraints;
 using webrtc::FakeVideoTrackRenderer;
 using webrtc::IceCandidateInterface;
@@ -32,9 +26,19 @@
 using webrtc::MediaStreamInterface;
 using webrtc::MockSetSessionDescriptionObserver;
 using webrtc::PeerConnectionInterface;
+using webrtc::SdpType;
 using webrtc::SessionDescriptionInterface;
 using webrtc::VideoTrackInterface;
 
+namespace {
+const char kStreamLabelBase[] = "stream_label";
+const char kVideoTrackLabelBase[] = "video_track";
+const char kAudioTrackLabelBase[] = "audio_track";
+constexpr int kMaxWait = 10000;
+constexpr int kTestAudioFrameCount = 3;
+constexpr int kTestVideoFrameCount = 3;
+}  // namespace
+
 void PeerConnectionTestWrapper::Connect(PeerConnectionTestWrapper* caller,
                                         PeerConnectionTestWrapper* callee) {
   caller->SignalOnIceCandidateReady.connect(
@@ -126,12 +130,13 @@
   EXPECT_TRUE(desc->ToString(&sdp));
 
   RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_ << ": "
-                   << desc->type() << " sdp created: " << sdp;
+                   << webrtc::SdpTypeToString(desc->GetType())
+                   << " sdp created: " << sdp;
 
   // Give the user a chance to modify sdp for testing.
   SignalOnSdpCreated(&sdp);
 
-  SetLocalDescription(desc->type(), sdp);
+  SetLocalDescription(desc->GetType(), sdp);
 
   SignalOnSdpReady(sdp);
 }
@@ -150,36 +155,38 @@
 }
 
 void PeerConnectionTestWrapper::ReceiveOfferSdp(const std::string& sdp) {
-  SetRemoteDescription(SessionDescriptionInterface::kOffer, sdp);
+  SetRemoteDescription(SdpType::kOffer, sdp);
   CreateAnswer(NULL);
 }
 
 void PeerConnectionTestWrapper::ReceiveAnswerSdp(const std::string& sdp) {
-  SetRemoteDescription(SessionDescriptionInterface::kAnswer, sdp);
+  SetRemoteDescription(SdpType::kAnswer, sdp);
 }
 
-void PeerConnectionTestWrapper::SetLocalDescription(const std::string& type,
+void PeerConnectionTestWrapper::SetLocalDescription(SdpType type,
                                                     const std::string& sdp) {
   RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
-                   << ": SetLocalDescription " << type << " " << sdp;
+                   << ": SetLocalDescription " << webrtc::SdpTypeToString(type)
+                   << " " << sdp;
 
   rtc::scoped_refptr<MockSetSessionDescriptionObserver>
       observer(new rtc::RefCountedObject<
                    MockSetSessionDescriptionObserver>());
   peer_connection_->SetLocalDescription(
-      observer, webrtc::CreateSessionDescription(type, sdp, NULL));
+      observer, webrtc::CreateSessionDescription(type, sdp).release());
 }
 
-void PeerConnectionTestWrapper::SetRemoteDescription(const std::string& type,
+void PeerConnectionTestWrapper::SetRemoteDescription(SdpType type,
                                                      const std::string& sdp) {
   RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
-                   << ": SetRemoteDescription " << type << " " << sdp;
+                   << ": SetRemoteDescription " << webrtc::SdpTypeToString(type)
+                   << " " << sdp;
 
   rtc::scoped_refptr<MockSetSessionDescriptionObserver>
       observer(new rtc::RefCountedObject<
                    MockSetSessionDescriptionObserver>());
   peer_connection_->SetRemoteDescription(
-      observer, webrtc::CreateSessionDescription(type, sdp, NULL));
+      observer, webrtc::CreateSessionDescription(type, sdp).release());
 }
 
 void PeerConnectionTestWrapper::AddIceCandidate(const std::string& sdp_mid,
diff --git a/pc/test/peerconnectiontestwrapper.h b/pc/test/peerconnectiontestwrapper.h
index aadaa8e..8d43ea9 100644
--- a/pc/test/peerconnectiontestwrapper.h
+++ b/pc/test/peerconnectiontestwrapper.h
@@ -89,8 +89,8 @@
   sigslot::signal1<webrtc::DataChannelInterface*> SignalOnDataChannel;
 
  private:
-  void SetLocalDescription(const std::string& type, const std::string& sdp);
-  void SetRemoteDescription(const std::string& type, const std::string& sdp);
+  void SetLocalDescription(webrtc::SdpType type, const std::string& sdp);
+  void SetRemoteDescription(webrtc::SdpType type, const std::string& sdp);
   bool CheckForConnection();
   bool CheckForAudio();
   bool CheckForVideo();
diff --git a/pc/webrtcsdp_unittest.cc b/pc/webrtcsdp_unittest.cc
index c4cd7db..a454c60 100644
--- a/pc/webrtcsdp_unittest.cc
+++ b/pc/webrtcsdp_unittest.cc
@@ -59,6 +59,7 @@
 using webrtc::RtpExtension;
 using webrtc::RtpTransceiverDirection;
 using webrtc::SdpParseError;
+using webrtc::SdpType;
 using webrtc::SessionDescriptionInterface;
 
 typedef std::vector<AudioCodec> AudioCodecs;
@@ -769,7 +770,7 @@
 static const int kDummyIndex = 123;
 
 // Misc
-static const char kDummyString[] = "dummy";
+static SdpType kDummyType = SdpType::kOffer;
 
 // Helper functions
 
@@ -803,7 +804,7 @@
 // message.
 static void ExpectParseFailure(const std::string& bad_sdp,
                                const std::string& bad_part) {
-  JsepSessionDescription desc(kDummyString);
+  JsepSessionDescription desc(kDummyType);
   SdpParseError error;
   bool ret = webrtc::SdpDeserialize(bad_sdp, &desc, &error);
   EXPECT_FALSE(ret);
@@ -865,8 +866,7 @@
 
 class WebRtcSdpTest : public testing::Test {
  public:
-  WebRtcSdpTest()
-     : jdesc_(kDummyString) {
+  WebRtcSdpTest() : jdesc_(kDummyType) {
 #ifdef WEBRTC_ANDROID
     webrtc::InitializeAndroidObjects();
 #endif
@@ -1494,7 +1494,7 @@
     std::string new_sdp = kSdpString;
     ReplaceRejected(audio_rejected, video_rejected, &new_sdp);
 
-    JsepSessionDescription jdesc_no_candidates(kDummyString);
+    JsepSessionDescription jdesc_no_candidates(kDummyType);
     MakeDescriptionWithoutCandidates(&jdesc_no_candidates);
     std::string message = webrtc::SdpSerialize(jdesc_no_candidates, false);
     EXPECT_EQ(new_sdp, message);
@@ -1538,7 +1538,7 @@
   bool TestDeserializeDirection(RtpTransceiverDirection direction) {
     std::string new_sdp = kSdpFullString;
     ReplaceDirection(direction, &new_sdp);
-    JsepSessionDescription new_jdesc(kDummyString);
+    JsepSessionDescription new_jdesc(kDummyType);
 
     EXPECT_TRUE(SdpDeserialize(new_sdp, &new_jdesc));
 
@@ -1556,7 +1556,7 @@
   bool TestDeserializeRejected(bool audio_rejected, bool video_rejected) {
     std::string new_sdp = kSdpString;
     ReplaceRejected(audio_rejected, video_rejected, &new_sdp);
-    JsepSessionDescription new_jdesc(JsepSessionDescription::kOffer);
+    JsepSessionDescription new_jdesc(SdpType::kOffer);
     EXPECT_TRUE(SdpDeserialize(new_sdp, &new_jdesc));
 
     audio_desc_ = static_cast<AudioContentDescription*>(
@@ -1573,7 +1573,7 @@
                    audio_rejected ? "" : kPwdVoice);
     SetIceUfragPwd(kVideoContentName, video_rejected ? "" : kUfragVideo,
                    video_rejected ? "" : kPwdVideo);
-    JsepSessionDescription jdesc_no_candidates(kDummyString);
+    JsepSessionDescription jdesc_no_candidates(kDummyType);
     if (!jdesc_no_candidates.Initialize(desc_.Copy(), jdesc_.session_id(),
                                         jdesc_.session_version())) {
       return false;
@@ -1585,11 +1585,11 @@
   void TestDeserializeExtmap(bool session_level, bool media_level,
       bool encrypted) {
     AddExtmap(encrypted);
-    JsepSessionDescription new_jdesc("dummy");
+    JsepSessionDescription new_jdesc(SdpType::kOffer);
     ASSERT_TRUE(new_jdesc.Initialize(desc_.Copy(),
                                      jdesc_.session_id(),
                                      jdesc_.session_version()));
-    JsepSessionDescription jdesc_with_extmap("dummy");
+    JsepSessionDescription jdesc_with_extmap(SdpType::kOffer);
     std::string sdp_with_extmap = kSdpString;
     if (session_level) {
       InjectAfter(kSessionTime,
@@ -1774,7 +1774,7 @@
   void TestSerialize(const JsepSessionDescription& jdesc,
                      bool unified_plan_sdp) {
     std::string message = webrtc::SdpSerialize(jdesc, unified_plan_sdp);
-    JsepSessionDescription jdesc_output_des(kDummyString);
+    JsepSessionDescription jdesc_output_des(kDummyType);
     SdpParseError error;
     EXPECT_TRUE(webrtc::SdpDeserialize(message, &jdesc_output_des, &error));
     EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output_des));
@@ -1823,7 +1823,7 @@
 }
 
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionEmpty) {
-  JsepSessionDescription jdesc_empty(kDummyString);
+  JsepSessionDescription jdesc_empty(kDummyType);
   EXPECT_EQ("", webrtc::SdpSerialize(jdesc_empty, false));
 }
 
@@ -1831,7 +1831,7 @@
 // the case in a DTLS offer.
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprint) {
   AddFingerprint();
-  JsepSessionDescription jdesc_with_fingerprint(kDummyString);
+  JsepSessionDescription jdesc_with_fingerprint(kDummyType);
   MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint);
   std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint, false);
 
@@ -1849,7 +1849,7 @@
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprintNoCryptos) {
   AddFingerprint();
   RemoveCryptos();
-  JsepSessionDescription jdesc_with_fingerprint(kDummyString);
+  JsepSessionDescription jdesc_with_fingerprint(kDummyType);
   MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint);
   std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint, false);
 
@@ -1866,7 +1866,7 @@
 
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithoutCandidates) {
   // JsepSessionDescription with desc but without candidates.
-  JsepSessionDescription jdesc_no_candidates(kDummyString);
+  JsepSessionDescription jdesc_no_candidates(kDummyType);
   MakeDescriptionWithoutCandidates(&jdesc_no_candidates);
   std::string message = webrtc::SdpSerialize(jdesc_no_candidates, false);
   EXPECT_EQ(std::string(kSdpString), message);
@@ -1958,7 +1958,7 @@
 
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithRtpDataChannel) {
   AddRtpDataChannel();
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
 
   MakeDescriptionWithoutCandidates(&jsep_desc);
   std::string message = webrtc::SdpSerialize(jsep_desc, false);
@@ -1971,7 +1971,7 @@
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithSctpDataChannel) {
   bool use_sctpmap = true;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
 
   MakeDescriptionWithoutCandidates(&jsep_desc);
   std::string message = webrtc::SdpSerialize(jsep_desc, false);
@@ -1984,7 +1984,7 @@
 TEST_F(WebRtcSdpTest, SerializeWithSctpDataChannelAndNewPort) {
   bool use_sctpmap = true;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
   MakeDescriptionWithoutCandidates(&jsep_desc);
   DataContentDescription* dcdesc = static_cast<DataContentDescription*>(
       jsep_desc.description()->GetContentDescriptionByName(kDataContentName));
@@ -2013,7 +2013,7 @@
 }
 
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithDataChannelAndBandwidth) {
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
   AddRtpDataChannel();
   data_desc_->set_bandwidth(100*1000);
   MakeDescriptionWithoutCandidates(&jsep_desc);
@@ -2031,7 +2031,7 @@
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithExtmap) {
   bool encrypted = false;
   AddExtmap(encrypted);
-  JsepSessionDescription desc_with_extmap("dummy");
+  JsepSessionDescription desc_with_extmap(kDummyType);
   MakeDescriptionWithoutCandidates(&desc_with_extmap);
   std::string message = webrtc::SdpSerialize(desc_with_extmap, false);
 
@@ -2047,7 +2047,7 @@
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithExtmapEncrypted) {
   bool encrypted = true;
   AddExtmap(encrypted);
-  JsepSessionDescription desc_with_extmap("dummy");
+  JsepSessionDescription desc_with_extmap(kDummyType);
   ASSERT_TRUE(desc_with_extmap.Initialize(desc_.Copy(),
                                           kSessionId, kSessionVersion));
   TestSerialize(desc_with_extmap, false);
@@ -2125,7 +2125,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescription) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   // Deserialize
   EXPECT_TRUE(SdpDeserialize(kSdpFullString, &jdesc));
   // Verify
@@ -2133,7 +2133,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutMline) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   const char kSdpWithoutMline[] =
     "v=0\r\n"
     "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
@@ -2146,7 +2146,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutCarriageReturn) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   std::string sdp_without_carriage_return = kSdpFullString;
   Replace("\r\n", "\n", &sdp_without_carriage_return);
   // Deserialize
@@ -2157,10 +2157,10 @@
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutCandidates) {
   // SessionDescription with desc but without candidates.
-  JsepSessionDescription jdesc_no_candidates(kDummyString);
+  JsepSessionDescription jdesc_no_candidates(kDummyType);
   ASSERT_TRUE(jdesc_no_candidates.Initialize(desc_.Copy(),
                                              kSessionId, kSessionVersion));
-  JsepSessionDescription new_jdesc(kDummyString);
+  JsepSessionDescription new_jdesc(kDummyType);
   EXPECT_TRUE(SdpDeserialize(kSdpString, &new_jdesc));
   EXPECT_TRUE(CompareSessionDescription(jdesc_no_candidates, new_jdesc));
 }
@@ -2178,7 +2178,7 @@
       "a=rtpmap:18 G729/16000\r\n"
       "a=rtpmap:103 ISAC/16000\r\n";
 
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   EXPECT_TRUE(SdpDeserialize(kSdpNoRtpmapString, &jdesc));
   cricket::AudioContentDescription* audio =
     static_cast<AudioContentDescription*>(
@@ -2202,7 +2202,7 @@
       "a=fmtp:18 annexb=yes\r\n"
       "a=rtpmap:103 ISAC/16000\r\n";
 
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   EXPECT_TRUE(SdpDeserialize(kSdpNoRtpmapString, &jdesc));
   cricket::AudioContentDescription* audio =
     static_cast<AudioContentDescription*>(
@@ -2227,12 +2227,12 @@
 TEST_F(WebRtcSdpTest, DeserializeJsepSessionDescriptionWithFingerprint) {
   // Add a DTLS a=fingerprint attribute to our session description.
   AddFingerprint();
-  JsepSessionDescription new_jdesc(kDummyString);
+  JsepSessionDescription new_jdesc(kDummyType);
   ASSERT_TRUE(new_jdesc.Initialize(desc_.Copy(),
                                    jdesc_.session_id(),
                                    jdesc_.session_version()));
 
-  JsepSessionDescription jdesc_with_fingerprint(kDummyString);
+  JsepSessionDescription jdesc_with_fingerprint(kDummyType);
   std::string sdp_with_fingerprint = kSdpString;
   InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_fingerprint);
   InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_fingerprint);
@@ -2241,7 +2241,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithBundle) {
-  JsepSessionDescription jdesc_with_bundle(kDummyString);
+  JsepSessionDescription jdesc_with_bundle(kDummyType);
   std::string sdp_with_bundle = kSdpFullString;
   InjectAfter(kSessionTime,
               "a=group:BUNDLE audio_content_name video_content_name\r\n",
@@ -2258,7 +2258,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithBandwidth) {
-  JsepSessionDescription jdesc_with_bandwidth(kDummyString);
+  JsepSessionDescription jdesc_with_bandwidth(kDummyType);
   std::string sdp_with_bandwidth = kSdpFullString;
   InjectAfter("a=mid:video_content_name\r\na=sendrecv\r\n",
               "b=AS:100\r\n",
@@ -2281,7 +2281,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithIceOptions) {
-  JsepSessionDescription jdesc_with_ice_options(kDummyString);
+  JsepSessionDescription jdesc_with_ice_options(kDummyType);
   std::string sdp_with_ice_options = kSdpFullString;
   InjectAfter(kSessionTime,
               "a=ice-options:iceoption3\r\n",
@@ -2309,7 +2309,7 @@
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithUfragPwd) {
   // Remove the original ice-ufrag and ice-pwd
-  JsepSessionDescription jdesc_with_ufrag_pwd(kDummyString);
+  JsepSessionDescription jdesc_with_ufrag_pwd(kDummyType);
   std::string sdp_with_ufrag_pwd = kSdpFullString;
   EXPECT_TRUE(RemoveCandidateUfragPwd(&sdp_with_ufrag_pwd));
   // Add session level ufrag and pwd
@@ -2358,7 +2358,7 @@
 // msid for backward compatibility.
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutMsid) {
   jdesc_.description()->set_msid_supported(false);
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   std::string sdp_without_msid = kSdpFullString;
   Replace("msid", "xmsid", &sdp_without_msid);
   // Deserialize
@@ -2476,12 +2476,12 @@
 
 TEST_F(WebRtcSdpTest, DeserializeSdpWithRtpDataChannels) {
   AddRtpDataChannel();
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
 
   std::string sdp_with_data = kSdpString;
   sdp_with_data.append(kSdpRtpDataChannelString);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   // Deserialize
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
@@ -2492,12 +2492,12 @@
 TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannels) {
   bool use_sctpmap = true;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
 
   std::string sdp_with_data = kSdpString;
   sdp_with_data.append(kSdpSctpDataChannelString);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   // Verify with DTLS/SCTP (already in kSdpSctpDataChannelString).
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
@@ -2519,12 +2519,12 @@
 TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelsWithSctpPort) {
   bool use_sctpmap = false;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
 
   std::string sdp_with_data = kSdpString;
   sdp_with_data.append(kSdpSctpDataChannelStringWithSctpPort);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   // Verify with DTLS/SCTP (already in kSdpSctpDataChannelStringWithSctpPort).
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
@@ -2546,12 +2546,12 @@
 TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelsWithSctpColonPort) {
   bool use_sctpmap = false;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
 
   std::string sdp_with_data = kSdpString;
   sdp_with_data.append(kSdpSctpDataChannelStringWithSctpColonPort);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   // Verify with DTLS/SCTP.
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
@@ -2575,7 +2575,7 @@
 TEST_F(WebRtcSdpTest, DeserializeSdpWithMultiSctpPort) {
   bool use_sctpmap = true;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
 
   std::string sdp_with_data = kSdpString;
@@ -2583,7 +2583,7 @@
   sdp_with_data.append(kSdpSctpDataChannelString);
   // Append a=sctp-port attribute
   sdp_with_data.append("a=sctp-port 5000\r\n");
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   EXPECT_FALSE(SdpDeserialize(sdp_with_data, &jdesc_output));
 }
@@ -2594,7 +2594,7 @@
   sdp_with_data.append(kSdpSctpDataChannelString);
   // Remove the "\n" at the end.
   sdp_with_data = sdp_with_data.substr(0, sdp_with_data.size() - 1);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   EXPECT_FALSE(SdpDeserialize(sdp_with_data, &jdesc_output));
   // No crash is a pass.
@@ -2622,7 +2622,7 @@
   AddSctpDataChannel(use_sctpmap);
 
   // First setup the expected JsepSessionDescription.
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   MutateJsepSctpPort(&jdesc, desc_);
 
   // Then get the deserialized JsepSessionDescription.
@@ -2631,7 +2631,7 @@
   rtc::replace_substrs(kDefaultSctpPortStr, strlen(kDefaultSctpPortStr),
                        kUnusualSctpPortStr, strlen(kUnusualSctpPortStr),
                        &sdp_with_data);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
   EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output));
@@ -2642,7 +2642,7 @@
   bool use_sctpmap = false;
   AddSctpDataChannel(use_sctpmap);
 
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   MutateJsepSctpPort(&jdesc, desc_);
 
   // We need to test the deserialized JsepSessionDescription from
@@ -2654,7 +2654,7 @@
   rtc::replace_substrs(kDefaultSctpPortStr, strlen(kDefaultSctpPortStr),
                        kUnusualSctpPortStr, strlen(kUnusualSctpPortStr),
                        &sdp_with_data);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
   EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output));
@@ -2671,7 +2671,7 @@
   InjectAfter("a=mid:data_content_name\r\n",
               "b=AS:100\r\n",
               &sdp_with_bandwidth);
-  JsepSessionDescription jdesc_with_bandwidth(kDummyString);
+  JsepSessionDescription jdesc_with_bandwidth(kDummyType);
 
   EXPECT_FALSE(SdpDeserialize(sdp_with_bandwidth, &jdesc_with_bandwidth));
 }
@@ -2679,7 +2679,7 @@
 TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelsAndBandwidth) {
   bool use_sctpmap = true;
   AddSctpDataChannel(use_sctpmap);
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   DataContentDescription* dcd = static_cast<DataContentDescription*>(
      GetFirstDataContent(&desc_)->description);
   dcd->set_bandwidth(100 * 1000);
@@ -2690,7 +2690,7 @@
   InjectAfter("a=mid:data_content_name\r\n",
               "b=AS:100\r\n",
               &sdp_with_bandwidth);
-  JsepSessionDescription jdesc_with_bandwidth(kDummyString);
+  JsepSessionDescription jdesc_with_bandwidth(kDummyType);
 
   // SCTP has congestion control, so we shouldn't limit the bandwidth
   // as we do for RTP.
@@ -2725,7 +2725,7 @@
                         ::testing::Values(false, true));
 
 TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutEndLineBreak) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   std::string sdp = kSdpFullString;
   sdp = sdp.substr(0, sdp.size() - 2);  // Remove \r\n at the end.
   // Deserialize
@@ -2762,7 +2762,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSdpWithConferenceFlag) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
 
   // Deserialize
   EXPECT_TRUE(SdpDeserialize(kSdpConferenceString, &jdesc));
@@ -2780,7 +2780,7 @@
 }
 
 TEST_F(WebRtcSdpTest, SerializeSdpWithConferenceFlag) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
 
   // We tested deserialization already above, so just test that if we serialize
   // and deserialize the flag doesn't disappear.
@@ -2885,7 +2885,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSdpWithReorderedPltypes) {
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   const char kSdpWithReorderedPlTypesString[] =
       "v=0\r\n"
@@ -2912,7 +2912,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSerializeCodecParams) {
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   CodecParams params;
   params.max_ptime = 40;
   params.ptime = 30;
@@ -2927,20 +2927,20 @@
 
 TEST_F(WebRtcSdpTest, DeserializeSerializeRtcpFb) {
   const bool kUseWildcard = false;
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   TestDeserializeRtcpFb(&jdesc_output, kUseWildcard);
   TestSerialize(jdesc_output, false);
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSerializeRtcpFbWildcard) {
   const bool kUseWildcard = true;
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   TestDeserializeRtcpFb(&jdesc_output, kUseWildcard);
   TestSerialize(jdesc_output, false);
 }
 
 TEST_F(WebRtcSdpTest, DeserializeVideoFmtp) {
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   const char kSdpWithFmtpString[] =
       "v=0\r\n"
@@ -2974,7 +2974,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeVideoFmtpWithSprops) {
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   const char kSdpWithFmtpString[] =
       "v=0\r\n"
@@ -3010,7 +3010,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeVideoFmtpWithSpace) {
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   const char kSdpWithFmtpString[] =
       "v=0\r\n"
@@ -3122,7 +3122,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeSdpWithIceLite) {
-  JsepSessionDescription jdesc_with_icelite(kDummyString);
+  JsepSessionDescription jdesc_with_icelite(kDummyType);
   std::string sdp_with_icelite = kSdpFullString;
   EXPECT_TRUE(SdpDeserialize(sdp_with_icelite, &jdesc_with_icelite));
   cricket::SessionDescription* desc = jdesc_with_icelite.description();
@@ -3150,7 +3150,7 @@
 TEST_F(WebRtcSdpTest, RoundTripSdpWithSctpDataChannelsWithCandidates) {
   std::string sdp_with_data = kSdpString;
   sdp_with_data.append(kSdpSctpDataChannelWithCandidatesString);
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
 
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
   EXPECT_EQ(sdp_with_data, webrtc::SdpSerialize(jdesc_output, false));
@@ -3196,7 +3196,7 @@
 }
 
 TEST_F(WebRtcSdpTest, DeserializeDtlsSetupAttribute) {
-  JsepSessionDescription jdesc_with_dtlssetup(kDummyString);
+  JsepSessionDescription jdesc_with_dtlssetup(kDummyType);
   std::string sdp_with_dtlssetup = kSdpFullString;
   InjectAfter(kSessionTime,
               "a=setup:actpass\r\n",
@@ -3216,7 +3216,7 @@
 // Verifies that the order of the serialized m-lines follows the order of the
 // ContentInfo in SessionDescription, and vise versa for deserialization.
 TEST_F(WebRtcSdpTest, MediaContentOrderMaintainedRoundTrip) {
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   const std::string media_content_sdps[3] = {
     kSdpAudioString,
     kSdpVideoString,
@@ -3260,7 +3260,7 @@
 
 TEST_F(WebRtcSdpTest, DeserializeBundleOnlyAttribute) {
   MakeBundleOnlyDescription();
-  JsepSessionDescription deserialized_description(kDummyString);
+  JsepSessionDescription deserialized_description(kDummyType);
   ASSERT_TRUE(
       SdpDeserialize(kBundleOnlySdpFullString, &deserialized_description));
   EXPECT_TRUE(CompareSessionDescription(jdesc_, deserialized_description));
@@ -3276,7 +3276,7 @@
 
   std::string modified_sdp = kBundleOnlySdpFullString;
   Replace("m=video 0", "m=video 9", &modified_sdp);
-  JsepSessionDescription deserialized_description(kDummyString);
+  JsepSessionDescription deserialized_description(kDummyType);
   ASSERT_TRUE(SdpDeserialize(modified_sdp, &deserialized_description));
   EXPECT_TRUE(CompareSessionDescription(jdesc_, deserialized_description));
 }
@@ -3289,7 +3289,7 @@
 TEST_F(WebRtcSdpTest, DeserializePlanBSessionDescription) {
   MakePlanBDescription();
 
-  JsepSessionDescription deserialized_description(kDummyString);
+  JsepSessionDescription deserialized_description(kDummyType);
   EXPECT_TRUE(SdpDeserialize(kPlanBSdpFullString, &deserialized_description));
 
   EXPECT_TRUE(CompareSessionDescription(jdesc_, deserialized_description));
@@ -3307,7 +3307,7 @@
 TEST_F(WebRtcSdpTest, DeserializePlanBSessionDescriptionWithMsid) {
   MakePlanBDescription();
 
-  JsepSessionDescription deserialized_description(kDummyString);
+  JsepSessionDescription deserialized_description(kDummyType);
   EXPECT_TRUE(
       SdpDeserialize(kPlanBSdpFullStringWithMsid, &deserialized_description));
 
@@ -3317,7 +3317,7 @@
 TEST_F(WebRtcSdpTest, DeserializeUnifiedPlanSessionDescription) {
   MakeUnifiedPlanDescription();
 
-  JsepSessionDescription deserialized_description(kDummyString);
+  JsepSessionDescription deserialized_description(kDummyType);
   EXPECT_TRUE(
       SdpDeserialize(kUnifiedPlanSdpFullString, &deserialized_description));
 
@@ -3393,7 +3393,7 @@
       "m=video 3457 RTP/SAVPF 120\r\n"
       "b=AS:-1\r\n";
 
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   EXPECT_TRUE(SdpDeserialize(kSdpWithBandwidthOfNegativeOne, &jdesc_output));
   const ContentInfo* vc = GetFirstVideoContent(jdesc_output.description());
   ASSERT_NE(nullptr, vc);
@@ -3421,7 +3421,7 @@
       "a=candidate:a0+B/1 1 udp 2130706432 192.168.1.5 1234 typ host "
       "generation 2 ufrag foo pwd bar\r\n";
 
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   EXPECT_TRUE(
       SdpDeserialize(kSdpWithIceCredentialsInCandidateString, &jdesc_output));
   const IceCandidateCollection* candidates = jdesc_output.candidates(0);
@@ -3450,7 +3450,7 @@
       "a=candidate:a0+B/1 1 udp 2130706432 192.168.1.5 12345678 typ host "
       "generation 2 raddr 192.168.1.1 rport 87654321\r\n";
 
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   EXPECT_FALSE(SdpDeserialize(kSdpWithInvalidCandidatePort, &jdesc_output));
 }
 
@@ -3468,7 +3468,7 @@
       "a=rtpmap:111 opus/48000/2\r\n"
       "a=msid:stream_id \r\n";
 
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   EXPECT_FALSE(SdpDeserialize(kSdpWithMissingTrackId, &jdesc_output));
 }
 
@@ -3483,14 +3483,14 @@
       "a=rtpmap:111 opus/48000/2\r\n"
       "a=msid: track_id\r\n";
 
-  JsepSessionDescription jdesc_output(kDummyString);
+  JsepSessionDescription jdesc_output(kDummyType);
   EXPECT_FALSE(SdpDeserialize(kSdpWithMissingStreamId, &jdesc_output));
 }
 
 // Tests that if both session-level address and media-level address exist, use
 // the media-level address.
 TEST_F(WebRtcSdpTest, ParseConnectionData) {
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
 
   // Sesssion-level address.
   std::string sdp = kSdpFullString;
@@ -3512,7 +3512,7 @@
 // Tests that the session-level connection address will be used if the media
 // level-addresses are not specified.
 TEST_F(WebRtcSdpTest, ParseConnectionDataSessionLevelOnly) {
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
 
   // Sesssion-level address.
   std::string sdp = kSdpString;
@@ -3535,7 +3535,7 @@
 }
 
 TEST_F(WebRtcSdpTest, ParseConnectionDataIPv6) {
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
 
   std::string sdp = kSdpString;
   EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc));
@@ -3562,7 +3562,7 @@
 
 // Test that the invalid or unsupprted connection data cannot be parsed.
 TEST_F(WebRtcSdpTest, ParseConnectionDataFailure) {
-  JsepSessionDescription jsep_desc(kDummyString);
+  JsepSessionDescription jsep_desc(kDummyType);
   std::string sdp = kSdpString;
   EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc));
 
@@ -3588,12 +3588,12 @@
 }
 
 TEST_F(WebRtcSdpTest, SerializeAndDeserializeWithConnectionAddress) {
-  JsepSessionDescription expected_jsep(kDummyString);
+  JsepSessionDescription expected_jsep(kDummyType);
   MakeDescriptionWithoutCandidates(&expected_jsep);
   // Serialization.
   std::string message = webrtc::SdpSerialize(expected_jsep, false);
   // Deserialization.
-  JsepSessionDescription jdesc(kDummyString);
+  JsepSessionDescription jdesc(kDummyType);
   EXPECT_TRUE(SdpDeserialize(message, &jdesc));
   auto audio_desc = static_cast<cricket::MediaContentDescription*>(
       jdesc.description()->GetContentByName(kAudioContentName)->description);
diff --git a/pc/webrtcsessiondescriptionfactory.cc b/pc/webrtcsessiondescriptionfactory.cc
index 18e9ba0..feec1fd 100644
--- a/pc/webrtcsessiondescriptionfactory.cc
+++ b/pc/webrtcsessiondescriptionfactory.cc
@@ -20,6 +20,7 @@
 #include "api/mediaconstraintsinterface.h"
 #include "pc/peerconnection.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/ptr_util.h"
 #include "rtc_base/sslidentity.h"
 
 using cricket::MediaSessionOptions;
@@ -251,7 +252,7 @@
     PostCreateSessionDescriptionFailed(observer, error);
     return;
   }
-  if (pc_->remote_description()->type() != JsepSessionDescription::kOffer) {
+  if (pc_->remote_description()->GetType() != SdpType::kOffer) {
     error += " failed because remote_description is not an offer.";
     RTC_LOG(LS_ERROR) << error;
     PostCreateSessionDescriptionFailed(observer, error);
@@ -343,11 +344,9 @@
   // is created regardless if it's identical to the previous one or not.
   // The |session_version_| is a uint64_t, the wrap around should not happen.
   RTC_DCHECK(session_version_ + 1 > session_version_);
-  JsepSessionDescription* offer(new JsepSessionDescription(
-      JsepSessionDescription::kOffer));
+  auto offer = rtc::MakeUnique<JsepSessionDescription>(SdpType::kOffer);
   if (!offer->Initialize(desc, session_id_,
                          rtc::ToString(session_version_++))) {
-    delete offer;
     PostCreateSessionDescriptionFailed(request.observer,
                                        "Failed to initialize the offer.");
     return;
@@ -357,11 +356,11 @@
          request.options.media_description_options) {
       if (!options.transport_options.ice_restart) {
         CopyCandidatesFromSessionDescription(pc_->local_description(),
-                                             options.mid, offer);
+                                             options.mid, offer.get());
       }
     }
   }
-  PostCreateSessionDescriptionSucceeded(request.observer, offer);
+  PostCreateSessionDescriptionSucceeded(request.observer, std::move(offer));
 }
 
 void WebRtcSessionDescriptionFactory::InternalCreateAnswer(
@@ -398,11 +397,9 @@
   // Get a new version number by increasing the |session_version_answer_|.
   // The |session_version_| is a uint64_t, the wrap around should not happen.
   RTC_DCHECK(session_version_ + 1 > session_version_);
-  JsepSessionDescription* answer(new JsepSessionDescription(
-      JsepSessionDescription::kAnswer));
+  auto answer = rtc::MakeUnique<JsepSessionDescription>(SdpType::kAnswer);
   if (!answer->Initialize(desc, session_id_,
                           rtc::ToString(session_version_++))) {
-    delete answer;
     PostCreateSessionDescriptionFailed(request.observer,
                                        "Failed to initialize the answer.");
     return;
@@ -414,11 +411,11 @@
          request.options.media_description_options) {
       if (!options.transport_options.ice_restart) {
         CopyCandidatesFromSessionDescription(pc_->local_description(),
-                                             options.mid, answer);
+                                             options.mid, answer.get());
       }
     }
   }
-  PostCreateSessionDescriptionSucceeded(request.observer, answer);
+  PostCreateSessionDescriptionSucceeded(request.observer, std::move(answer));
 }
 
 void WebRtcSessionDescriptionFactory::FailPendingRequests(
@@ -445,9 +442,9 @@
 
 void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded(
     CreateSessionDescriptionObserver* observer,
-    SessionDescriptionInterface* description) {
+    std::unique_ptr<SessionDescriptionInterface> description) {
   CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
-  msg->description.reset(description);
+  msg->description = std::move(description);
   signaling_thread_->Post(RTC_FROM_HERE, this,
                           MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg);
 }
diff --git a/pc/webrtcsessiondescriptionfactory.h b/pc/webrtcsessiondescriptionfactory.h
index 7ad418f..12d1cd2 100644
--- a/pc/webrtcsessiondescriptionfactory.h
+++ b/pc/webrtcsessiondescriptionfactory.h
@@ -137,7 +137,7 @@
       const std::string& error);
   void PostCreateSessionDescriptionSucceeded(
       CreateSessionDescriptionObserver* observer,
-      SessionDescriptionInterface* description);
+      std::unique_ptr<SessionDescriptionInterface> description);
 
   void OnCertificateRequestFailed();
   void SetCertificate(
diff --git a/sdk/android/src/jni/pc/java_native_conversion.cc b/sdk/android/src/jni/pc/java_native_conversion.cc
index f8f0763..52ccfec 100644
--- a/sdk/android/src/jni/pc/java_native_conversion.cc
+++ b/sdk/android/src/jni/pc/java_native_conversion.cc
@@ -82,8 +82,9 @@
                                  &NativeToJavaCandidate);
 }
 
-SessionDescriptionInterface* JavaToNativeSessionDescription(JNIEnv* jni,
-                                                            jobject j_sdp) {
+std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
+    JNIEnv* jni,
+    jobject j_sdp) {
   jfieldID j_type_id = GetFieldID(jni, GetObjectClass(jni, j_sdp), "type",
                                   "Lorg/webrtc/SessionDescription$Type;");
   jobject j_type = GetObjectField(jni, j_sdp, j_type_id);
@@ -94,13 +95,18 @@
       (jstring)jni->CallObjectMethod(j_type, j_canonical_form_id);
   CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
   std::string std_type = JavaToStdString(jni, j_type_string);
+  rtc::Optional<SdpType> sdp_type_maybe = SdpTypeFromString(std_type);
+  if (!sdp_type_maybe) {
+    RTC_LOG(LS_ERROR) << "Unexpected SDP type: " << std_type;
+    return nullptr;
+  }
 
   jfieldID j_description_id = GetFieldID(jni, GetObjectClass(jni, j_sdp),
                                          "description", "Ljava/lang/String;");
   jstring j_description = (jstring)GetObjectField(jni, j_sdp, j_description_id);
   std::string std_description = JavaToStdString(jni, j_description);
 
-  return CreateSessionDescription(std_type, std_description, NULL);
+  return CreateSessionDescription(*sdp_type_maybe, std_description);
 }
 
 jobject NativeToJavaSessionDescription(
diff --git a/sdk/android/src/jni/pc/java_native_conversion.h b/sdk/android/src/jni/pc/java_native_conversion.h
index ecdbf1b..c3580f5 100644
--- a/sdk/android/src/jni/pc/java_native_conversion.h
+++ b/sdk/android/src/jni/pc/java_native_conversion.h
@@ -45,8 +45,9 @@
     JNIEnv* jni,
     const std::vector<cricket::Candidate>& candidates);
 
-SessionDescriptionInterface* JavaToNativeSessionDescription(JNIEnv* jni,
-                                                            jobject j_sdp);
+std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
+    JNIEnv* jni,
+    jobject j_sdp);
 
 jobject NativeToJavaSessionDescription(JNIEnv* jni,
                                        const SessionDescriptionInterface* desc);
diff --git a/sdk/android/src/jni/pc/peerconnection_jni.cc b/sdk/android/src/jni/pc/peerconnection_jni.cc
index fbb2bf7..3867ec9 100644
--- a/sdk/android/src/jni/pc/peerconnection_jni.cc
+++ b/sdk/android/src/jni/pc/peerconnection_jni.cc
@@ -149,7 +149,7 @@
   rtc::scoped_refptr<SetSdpObserverJni> observer(
       new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
   ExtractNativePC(jni, j_pc)->SetLocalDescription(
-      observer, JavaToNativeSessionDescription(jni, j_sdp));
+      observer, JavaToNativeSessionDescription(jni, j_sdp).release());
 }
 
 JNI_FUNCTION_DECLARATION(void,
@@ -161,7 +161,7 @@
   rtc::scoped_refptr<SetSdpObserverJni> observer(
       new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
   ExtractNativePC(jni, j_pc)->SetRemoteDescription(
-      observer, JavaToNativeSessionDescription(jni, j_sdp));
+      observer, JavaToNativeSessionDescription(jni, j_sdp).release());
 }
 
 JNI_FUNCTION_DECLARATION(void,