Add signaling to support ICE renomination.
By default, this will tell the remote side that I am supporting ICE renomination.
It does not use ICE renomination yet even if the remote side supports it.

R=deadbeef@webrtc.org, pthatcher@webrtc.org, skvlad@webrtc.org

Review URL: https://codereview.webrtc.org/2224563004 .

Cr-Commit-Position: refs/heads/master@{#13998}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index b13113a..bdd33d7 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -633,6 +633,8 @@
 
   stats_.reset(new StatsCollector(this));
 
+  enable_ice_renomination_ = configuration.enable_ice_renomination;
+
   // Initialize the WebRtcSession. It creates transport channels etc.
   if (!session_->Initialize(factory_->options(), std::move(cert_generator),
                             configuration)) {
@@ -1262,6 +1264,8 @@
 
   // TODO(deadbeef): Shouldn't have to hop to the worker thread twice...
   session_->SetIceConfig(session_->ParseIceConfig(configuration));
+
+  enable_ice_renomination_ = configuration.enable_ice_renomination;
   return true;
 }
 
@@ -1615,6 +1619,8 @@
           cricket::TransportOptions();
     }
   }
+  session_options->enable_ice_renomination = enable_ice_renomination_;
+
   if (!ExtractMediaSessionOptions(rtc_options, true, session_options)) {
     return false;
   }
@@ -1651,6 +1657,13 @@
   return true;
 }
 
+void PeerConnection::InitializeOptionsForAnswer(
+    cricket::MediaSessionOptions* session_options) {
+  session_options->recv_audio = false;
+  session_options->recv_video = false;
+  session_options->enable_ice_renomination = enable_ice_renomination_;
+}
+
 void PeerConnection::FinishOptionsForAnswer(
     cricket::MediaSessionOptions* session_options) {
   // TODO(deadbeef): Once we have transceivers, enumerate them here instead of
@@ -1685,8 +1698,7 @@
 bool PeerConnection::GetOptionsForAnswer(
     const MediaConstraintsInterface* constraints,
     cricket::MediaSessionOptions* session_options) {
-  session_options->recv_audio = false;
-  session_options->recv_video = false;
+  InitializeOptionsForAnswer(session_options);
   if (!ParseConstraintsForAnswer(constraints, session_options)) {
     return false;
   }
@@ -1699,8 +1711,7 @@
 bool PeerConnection::GetOptionsForAnswer(
     const RTCOfferAnswerOptions& options,
     cricket::MediaSessionOptions* session_options) {
-  session_options->recv_audio = false;
-  session_options->recv_video = false;
+  InitializeOptionsForAnswer(session_options);
   if (!ExtractMediaSessionOptions(options, false, session_options)) {
     return false;
   }
diff --git a/webrtc/api/peerconnection.h b/webrtc/api/peerconnection.h
index c4a9a60..042e7f1 100644
--- a/webrtc/api/peerconnection.h
+++ b/webrtc/api/peerconnection.h
@@ -239,6 +239,9 @@
       const RTCOfferAnswerOptions& options,
       cricket::MediaSessionOptions* session_options);
 
+  void InitializeOptionsForAnswer(
+      cricket::MediaSessionOptions* session_options);
+
   // Helper function for options processing.
   // Deprecated.
   virtual void FinishOptionsForAnswer(
@@ -414,6 +417,8 @@
 
   bool remote_peer_supports_msid_ = false;
 
+  bool enable_ice_renomination_ = false;
+
   std::vector<rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>>
       senders_;
   std::vector<
diff --git a/webrtc/api/peerconnection_unittest.cc b/webrtc/api/peerconnection_unittest.cc
index 33b7b2f..fb3c188 100644
--- a/webrtc/api/peerconnection_unittest.cc
+++ b/webrtc/api/peerconnection_unittest.cc
@@ -393,6 +393,15 @@
 
   bool ExpectIceRestart() const { return expect_ice_restart_; }
 
+  void SetExpectIceRenomination(bool expect_renomination) {
+    expect_ice_renomination_ = expect_renomination;
+  }
+  void SetExpectRemoteIceRenomination(bool expect_renomination) {
+    expect_remote_ice_renomination_ = expect_renomination;
+  }
+  bool ExpectIceRenomination() { return expect_ice_renomination_; }
+  bool ExpectRemoteIceRenomination() { return expect_remote_ice_renomination_; }
+
   void SetReceiveAudioVideo(bool audio, bool video) {
     SetReceiveAudio(audio);
     SetReceiveVideo(video);
@@ -670,6 +679,42 @@
     }
   }
 
+  void VerifyLocalIceRenomination() {
+    ASSERT_TRUE(peer_connection_->local_description() != nullptr);
+    const cricket::SessionDescription* desc =
+        peer_connection_->local_description()->description();
+    const cricket::ContentInfos& contents = desc->contents();
+
+    for (auto content : contents) {
+      if (content.rejected)
+        continue;
+      const cricket::TransportDescription* transport_desc =
+          desc->GetTransportDescriptionByName(content.name);
+      const auto& options = transport_desc->transport_options;
+      auto iter = std::find(options.begin(), options.end(),
+                            cricket::ICE_RENOMINATION_STR);
+      EXPECT_EQ(ExpectIceRenomination(), iter != options.end());
+    }
+  }
+
+  void VerifyRemoteIceRenomination() {
+    ASSERT_TRUE(peer_connection_->remote_description() != nullptr);
+    const cricket::SessionDescription* desc =
+        peer_connection_->remote_description()->description();
+    const cricket::ContentInfos& contents = desc->contents();
+
+    for (auto content : contents) {
+      if (content.rejected)
+        continue;
+      const cricket::TransportDescription* transport_desc =
+          desc->GetTransportDescriptionByName(content.name);
+      const auto& options = transport_desc->transport_options;
+      auto iter = std::find(options.begin(), options.end(),
+                            cricket::ICE_RENOMINATION_STR);
+      EXPECT_EQ(ExpectRemoteIceRenomination(), iter != options.end());
+    }
+  }
+
   int GetAudioOutputLevelStats(webrtc::MediaStreamTrackInterface* track) {
     rtc::scoped_refptr<MockStatsObserver>
         observer(new rtc::RefCountedObject<MockStatsObserver>());
@@ -1030,6 +1075,8 @@
   typedef std::pair<std::string, std::string> IceUfragPwdPair;
   std::map<int, IceUfragPwdPair> ice_ufrag_pwd_;
   bool expect_ice_restart_ = false;
+  bool expect_ice_renomination_ = false;
+  bool expect_remote_ice_renomination_ = false;
 
   // Needed to keep track of number of frames sent.
   rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
@@ -2128,6 +2175,32 @@
   EXPECT_NE(receiver_candidate, receiver_candidate_restart);
 }
 
+TEST_F(P2PTestConductor, IceRenominationDisabled) {
+  config()->enable_ice_renomination = false;
+  ASSERT_TRUE(CreateTestClients());
+  LocalP2PTest();
+
+  initializing_client()->VerifyLocalIceRenomination();
+  receiving_client()->VerifyLocalIceRenomination();
+  initializing_client()->VerifyRemoteIceRenomination();
+  receiving_client()->VerifyRemoteIceRenomination();
+}
+
+TEST_F(P2PTestConductor, IceRenominationEnabled) {
+  config()->enable_ice_renomination = true;
+  ASSERT_TRUE(CreateTestClients());
+  initializing_client()->SetExpectIceRenomination(true);
+  initializing_client()->SetExpectRemoteIceRenomination(true);
+  receiving_client()->SetExpectIceRenomination(true);
+  receiving_client()->SetExpectRemoteIceRenomination(true);
+  LocalP2PTest();
+
+  initializing_client()->VerifyLocalIceRenomination();
+  receiving_client()->VerifyLocalIceRenomination();
+  initializing_client()->VerifyRemoteIceRenomination();
+  receiving_client()->VerifyRemoteIceRenomination();
+}
+
 // This test sets up a call between two parties with audio, and video.
 // It then renegotiates setting the video m-line to "port 0", then later
 // renegotiates again, enabling video.
diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h
index 1dba14c..624c67f 100644
--- a/webrtc/api/peerconnectioninterface.h
+++ b/webrtc/api/peerconnectioninterface.h
@@ -317,6 +317,9 @@
     // If set to true, this means the ICE transport should presume TURN-to-TURN
     // candidate pairs will succeed, even before a binding response is received.
     bool presume_writable_when_fully_relayed = false;
+    // If true, "renomination" will be added to the ice options in the transport
+    // description.
+    bool enable_ice_renomination = false;
     // If true, ICE role is redetermined when peerconnection sets a local
     // transport description that indicates an ICE restart.
     bool redetermine_role_on_ice_restart = true;
@@ -329,18 +332,13 @@
     // The default value for constraint offerToReceiveX:true.
     static const int kOfferToReceiveMediaTrue = 1;
 
-    int offer_to_receive_video;
-    int offer_to_receive_audio;
-    bool voice_activity_detection;
-    bool ice_restart;
-    bool use_rtp_mux;
+    int offer_to_receive_video = kUndefined;
+    int offer_to_receive_audio = kUndefined;
+    bool voice_activity_detection = true;
+    bool ice_restart = false;
+    bool use_rtp_mux = true;
 
-    RTCOfferAnswerOptions()
-        : offer_to_receive_video(kUndefined),
-          offer_to_receive_audio(kUndefined),
-          voice_activity_detection(true),
-          ice_restart(false),
-          use_rtp_mux(true) {}
+    RTCOfferAnswerOptions() = default;
 
     RTCOfferAnswerOptions(int offer_to_receive_video,
                           int offer_to_receive_audio,