Chromium Code Reviews| Index: talk/app/webrtc/webrtcsession.cc |
| diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc |
| index 5957cae8aeb2bd8211d80f6e74c4a06e45339689..b37cc660b766e84d4ea149eab38e93ea3614308e 100644 |
| --- a/talk/app/webrtc/webrtcsession.cc |
| +++ b/talk/app/webrtc/webrtcsession.cc |
| @@ -474,24 +474,21 @@ uint32_t ConvertIceTransportTypeToCandidateFilter( |
| return cricket::CF_NONE; |
| } |
| -// Help class used to remember if a a remote peer has requested ice restart by |
| -// by sending a description with new ice ufrag and password. |
| +// Helper class used to remember if a remote peer has requested an ICE restart |
| +// by sending a description with a new ICE ufrag and password. |
| class IceRestartAnswerLatch { |
| public: |
| - IceRestartAnswerLatch() : ice_restart_(false) { } |
| + IceRestartAnswerLatch(cricket::MediaType media_type) |
| + : ice_restart_(false), media_type_(media_type) {} |
| // Returns true if CheckForRemoteIceRestart has been called with a new session |
| - // description where ice password and ufrag has changed since last time |
| + // description where the ICE password and ufrag has changed since last time |
| // Reset() was called. |
| bool Get() const { |
| return ice_restart_; |
| } |
| - void Reset() { |
| - if (ice_restart_) { |
| - ice_restart_ = false; |
| - } |
| - } |
| + void Reset() { ice_restart_ = false; } |
| // This method has two purposes: 1. Return whether |new_desc| requests |
| // an ICE restart (i.e., new ufrag/pwd). 2. If it requests an ICE restart |
| @@ -504,38 +501,35 @@ class IceRestartAnswerLatch { |
| } |
| const SessionDescription* new_sd = new_desc->description(); |
| const SessionDescription* old_sd = old_desc->description(); |
| - const ContentInfos& contents = new_sd->contents(); |
| - for (size_t index = 0; index < contents.size(); ++index) { |
| - const ContentInfo* cinfo = &contents[index]; |
| - if (cinfo->rejected) { |
| - continue; |
| - } |
| - // If the content isn't rejected, check if ufrag and password has |
| - // changed. |
| - const cricket::TransportDescription* new_transport_desc = |
| - new_sd->GetTransportDescriptionByName(cinfo->name); |
| - const cricket::TransportDescription* old_transport_desc = |
| - old_sd->GetTransportDescriptionByName(cinfo->name); |
| - if (!new_transport_desc || !old_transport_desc) { |
| - // No transport description exist. This is not an ice restart. |
| - continue; |
| - } |
| - if (cricket::IceCredentialsChanged(old_transport_desc->ice_ufrag, |
| - old_transport_desc->ice_pwd, |
| - new_transport_desc->ice_ufrag, |
| - new_transport_desc->ice_pwd)) { |
| - LOG(LS_INFO) << "Remote peer request ice restart."; |
| - if (new_desc->type() == SessionDescriptionInterface::kOffer) { |
| - ice_restart_ = true; |
| - } |
| - return true; |
| + const ContentInfo* cinfo = |
| + GetFirstMediaContent(new_sd->contents(), media_type_); |
| + if (!cinfo || cinfo->rejected) { |
| + return false; |
| + } |
| + // If the content isn't rejected, check if ufrag and password has changed. |
| + const cricket::TransportDescription* new_transport_desc = |
| + new_sd->GetTransportDescriptionByName(cinfo->name); |
| + const cricket::TransportDescription* old_transport_desc = |
| + old_sd->GetTransportDescriptionByName(cinfo->name); |
| + if (!new_transport_desc || !old_transport_desc) { |
| + // No transport description exists. This is not an ICE restart. |
| + return false; |
| + } |
| + if (cricket::IceCredentialsChanged( |
| + old_transport_desc->ice_ufrag, old_transport_desc->ice_pwd, |
| + new_transport_desc->ice_ufrag, new_transport_desc->ice_pwd)) { |
| + LOG(LS_INFO) << "Remote peer request ice restart."; |
| + if (new_desc->type() == SessionDescriptionInterface::kOffer) { |
| + ice_restart_ = true; |
| } |
| + return true; |
| } |
| return false; |
| } |
| private: |
| bool ice_restart_; |
| + cricket::MediaType media_type_; |
| }; |
| WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller, |
| @@ -560,7 +554,12 @@ WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller, |
| older_version_remote_peer_(false), |
| dtls_enabled_(false), |
| data_channel_type_(cricket::DCT_NONE), |
| - ice_restart_latch_(new IceRestartAnswerLatch), |
| + audio_ice_restart_latch_( |
| + new IceRestartAnswerLatch(cricket::MEDIA_TYPE_AUDIO)), |
| + video_ice_restart_latch_( |
| + new IceRestartAnswerLatch(cricket::MEDIA_TYPE_VIDEO)), |
| + data_ice_restart_latch_( |
| + new IceRestartAnswerLatch(cricket::MEDIA_TYPE_DATA)), |
| metrics_observer_(NULL) { |
| transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); |
| transport_controller_->SignalConnectionState.connect( |
| @@ -812,6 +811,10 @@ bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc, |
| UseCandidatesInSessionDescription(remote_desc_.get()); |
| } |
| + audio_ice_restart_latch_->Reset(); |
| + video_ice_restart_latch_->Reset(); |
| + data_ice_restart_latch_->Reset(); |
| + |
| if (error() != ERROR_NONE) { |
| return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); |
| } |
| @@ -857,18 +860,31 @@ bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, |
| // Check if this new SessionDescription contains new ice ufrag and password |
| // that indicates the remote peer requests ice restart. |
| - bool ice_restart = |
| - ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), desc); |
| - // We retain all received candidates only if ICE is not restarted. |
| - // When ICE is restarted, all previous candidates belong to an old generation |
| - // and should not be kept. |
| - // TODO(deadbeef): This goes against the W3C spec which says the remote |
| - // description should only contain candidates from the last set remote |
| - // description plus any candidates added since then. We should remove this |
| - // once we're sure it won't break anything. |
| - if (!ice_restart) { |
| + // TODO(deadbeef): When we start storing both the current and pending remote |
| + // description, this should reset the latch and compare against the current |
| + // description. |
| + if (!audio_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), |
| + desc)) { |
| + // We retain all received candidates only if ICE is not restarted. |
| + // When ICE is restarted, all previous candidates belong to an old |
| + // generation |
|
honghaiz3
2016/02/10 01:01:48
This and the next line can be merged.
Taylor Brandstetter
2016/02/10 21:18:32
Done.
|
| + // and should not be kept. |
| + // TODO(deadbeef): This goes against the W3C spec which says the remote |
| + // description should only contain candidates from the last set remote |
| + // description plus any candidates added since then. We should remove this |
| + // once we're sure it won't break anything. |
| + WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| + old_remote_desc.get(), cricket::MEDIA_TYPE_AUDIO, desc); |
| + } |
| + if (!video_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), |
| + desc)) { |
| WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| - old_remote_desc.get(), desc); |
| + old_remote_desc.get(), cricket::MEDIA_TYPE_VIDEO, desc); |
| + } |
| + if (!data_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), |
| + desc)) { |
| + WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| + old_remote_desc.get(), cricket::MEDIA_TYPE_DATA, desc); |
| } |
| if (error() != ERROR_NONE) { |
| @@ -1465,12 +1481,16 @@ cricket::DataChannelType WebRtcSession::data_channel_type() const { |
| return data_channel_type_; |
| } |
| -bool WebRtcSession::IceRestartPending() const { |
| - return ice_restart_latch_->Get(); |
| +bool WebRtcSession::AudioIceRestartPending() const { |
| + return audio_ice_restart_latch_->Get(); |
| +} |
| + |
| +bool WebRtcSession::VideoIceRestartPending() const { |
| + return video_ice_restart_latch_->Get(); |
| } |
| -void WebRtcSession::ResetIceRestartLatch() { |
| - ice_restart_latch_->Reset(); |
| +bool WebRtcSession::DataIceRestartPending() const { |
| + return data_ice_restart_latch_->Get(); |
| } |
| void WebRtcSession::OnCertificateReady( |