| Index: talk/app/webrtc/webrtcsession_unittest.cc
 | 
| diff --git a/talk/app/webrtc/webrtcsession_unittest.cc b/talk/app/webrtc/webrtcsession_unittest.cc
 | 
| index c553165f9b57f523e965d3d82efbee3fb37461b2..591d0c00eaf86cd52345dc05606bde8be5556eb5 100644
 | 
| --- a/talk/app/webrtc/webrtcsession_unittest.cc
 | 
| +++ b/talk/app/webrtc/webrtcsession_unittest.cc
 | 
| @@ -793,6 +793,34 @@ class WebRtcSessionTest
 | 
|      EXPECT_TRUE(expect_equal);
 | 
|    }
 | 
|  
 | 
| +  // Compares ufrag/password only for the specified media type.
 | 
| +  void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
 | 
| +                                  const cricket::SessionDescription* desc2,
 | 
| +                                  cricket::MediaType media_type,
 | 
| +                                  bool expect_equal) {
 | 
| +    if (desc1->contents().size() != desc2->contents().size()) {
 | 
| +      EXPECT_FALSE(expect_equal);
 | 
| +      return;
 | 
| +    }
 | 
| +
 | 
| +    const cricket::ContentInfo* cinfo =
 | 
| +        cricket::GetFirstMediaContent(desc1->contents(), media_type);
 | 
| +    const cricket::TransportDescription* transport_desc1 =
 | 
| +        desc1->GetTransportDescriptionByName(cinfo->name);
 | 
| +    const cricket::TransportDescription* transport_desc2 =
 | 
| +        desc2->GetTransportDescriptionByName(cinfo->name);
 | 
| +    if (!transport_desc1 || !transport_desc2) {
 | 
| +      EXPECT_FALSE(expect_equal);
 | 
| +      return;
 | 
| +    }
 | 
| +    if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
 | 
| +        transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
 | 
| +      EXPECT_FALSE(expect_equal);
 | 
| +      return;
 | 
| +    }
 | 
| +    EXPECT_TRUE(expect_equal);
 | 
| +  }
 | 
| +
 | 
|    void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
 | 
|                                std::string *sdp) {
 | 
|      const cricket::SessionDescription* desc = current_desc->description();
 | 
| @@ -846,6 +874,24 @@ class WebRtcSessionTest
 | 
|      }
 | 
|    }
 | 
|  
 | 
| +  // Modifies ufrag/pwd for specified |media_type|, by directly modifying the
 | 
| +  // description.
 | 
| +  void ModifyIceUfragPwd(SessionDescriptionInterface* current_desc,
 | 
| +                         cricket::MediaType media_type,
 | 
| +                         const std::string& modified_ice_ufrag,
 | 
| +                         const std::string& modified_ice_pwd) {
 | 
| +    cricket::SessionDescription* desc = current_desc->description();
 | 
| +    const cricket::ContentInfo* cinfo =
 | 
| +        cricket::GetFirstMediaContent(desc->contents(), media_type);
 | 
| +    // Replace ufrag and pwd with |modified_ice_ufrag| and
 | 
| +    // |modified_ice_pwd| strings.
 | 
| +    TransportInfo* transport_info = desc->GetTransportInfoByName(cinfo->name);
 | 
| +    cricket::TransportDescription* transport_desc =
 | 
| +        &transport_info->description;
 | 
| +    transport_desc->ice_ufrag = modified_ice_ufrag;
 | 
| +    transport_desc->ice_pwd = modified_ice_pwd;
 | 
| +  }
 | 
| +
 | 
|    // Creates a remote offer and and applies it as a remote description,
 | 
|    // creates a local answer and applies is as a local description.
 | 
|    // Call SendAudioVideoStreamX() before this function
 | 
| @@ -3726,6 +3772,49 @@ TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
 | 
|    SetLocalDescriptionWithoutError(updated_answer2.release());
 | 
|  }
 | 
|  
 | 
| +// This test verifies that if an offer does an ICE restart on some, but not all
 | 
| +// media sections, the answer will change the ufrag/password in the correct
 | 
| +// media sections.
 | 
| +TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewAndOldUfragAndPassword) {
 | 
| +  Init();
 | 
| +  cricket::MediaSessionOptions options;
 | 
| +  options.recv_video = true;
 | 
| +  options.recv_audio = true;
 | 
| +  options.bundle_enabled = false;
 | 
| +  rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer(options));
 | 
| +
 | 
| +  ModifyIceUfragPwd(offer.get(), cricket::MEDIA_TYPE_AUDIO, "aaaa",
 | 
| +                    "aaaaaaaaaaaaaaaaaaaaaa");
 | 
| +  ModifyIceUfragPwd(offer.get(), cricket::MEDIA_TYPE_VIDEO, "bbbb",
 | 
| +                    "bbbbbbbbbbbbbbbbbbbbbb");
 | 
| +  SetRemoteDescriptionWithoutError(offer.release());
 | 
| +
 | 
| +  SendAudioVideoStream1();
 | 
| +  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(nullptr));
 | 
| +  SetLocalDescriptionWithoutError(answer.release());
 | 
| +
 | 
| +  // Receive an offer with new ufrag and password, but only for the video media
 | 
| +  // section.
 | 
| +  rtc::scoped_ptr<JsepSessionDescription> updated_offer(
 | 
| +      CreateRemoteOffer(options, session_->remote_description()));
 | 
| +  ModifyIceUfragPwd(updated_offer.get(), cricket::MEDIA_TYPE_VIDEO, "cccc",
 | 
| +                    "cccccccccccccccccccccc");
 | 
| +  SetRemoteDescriptionWithoutError(updated_offer.release());
 | 
| +
 | 
| +  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer(
 | 
| +      CreateAnswer(nullptr));
 | 
| +
 | 
| +  CompareIceUfragAndPassword(updated_answer->description(),
 | 
| +                             session_->local_description()->description(),
 | 
| +                             cricket::MEDIA_TYPE_AUDIO, true);
 | 
| +
 | 
| +  CompareIceUfragAndPassword(updated_answer->description(),
 | 
| +                             session_->local_description()->description(),
 | 
| +                             cricket::MEDIA_TYPE_VIDEO, false);
 | 
| +
 | 
| +  SetLocalDescriptionWithoutError(updated_answer.release());
 | 
| +}
 | 
| +
 | 
|  TEST_F(WebRtcSessionTest, TestSessionContentError) {
 | 
|    Init();
 | 
|    SendAudioVideoStream1();
 | 
| 
 |