| Index: third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
 | 
| diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
 | 
| index e4d46030e55e6c5fdeb58076043f34c5ef75beda..63866d30253d725e3f5ecd2e1316ba3f93ab8503 100644
 | 
| --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
 | 
| +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
 | 
| @@ -1110,6 +1110,8 @@ void RTCPeerConnection::addStream(ScriptState* script_state,
 | 
|    if (!valid)
 | 
|      exception_state.ThrowDOMException(kSyntaxError,
 | 
|                                        "Unable to add the provided stream.");
 | 
| +  // Ensure |rtp_senders_| is up-to-date.
 | 
| +  getSenders();
 | 
|  }
 | 
|  
 | 
|  void RTCPeerConnection::removeStream(MediaStream* stream,
 | 
| @@ -1236,6 +1238,75 @@ HeapVector<Member<RTCRtpReceiver>> RTCPeerConnection::getReceivers() {
 | 
|    return rtp_receivers;
 | 
|  }
 | 
|  
 | 
| +RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
 | 
| +                                          MediaStreamVector streams,
 | 
| +                                          ExceptionState& exception_state) {
 | 
| +  DCHECK(track);
 | 
| +  DCHECK(track->Component());
 | 
| +  if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state))
 | 
| +    return nullptr;
 | 
| +  if (streams.size() >= 2) {
 | 
| +    // TODO(hbos): Don't throw an exception when this is supported by the lower
 | 
| +    // layers. https://crbug.com/webrtc/7932
 | 
| +    exception_state.ThrowDOMException(
 | 
| +        kNotSupportedError,
 | 
| +        "Adding a track to multiple streams is not supported.");
 | 
| +    return nullptr;
 | 
| +  }
 | 
| +  for (const auto sender_entry : rtp_senders_) {
 | 
| +    RTCRtpSender* sender = sender_entry.value;
 | 
| +    if (sender->track() == track) {
 | 
| +      exception_state.ThrowDOMException(
 | 
| +          kInvalidAccessError, "A sender already exists for the track.");
 | 
| +      return nullptr;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  WebVector<WebMediaStream> web_streams(streams.size());
 | 
| +  for (size_t i = 0; i < streams.size(); ++i) {
 | 
| +    web_streams[i] = streams[i]->Descriptor();
 | 
| +  }
 | 
| +  std::unique_ptr<WebRTCRtpSender> web_rtp_sender =
 | 
| +      peer_handler_->AddTrack(track->Component(), web_streams);
 | 
| +  if (!web_rtp_sender) {
 | 
| +    exception_state.ThrowDOMException(
 | 
| +        kNotSupportedError, "A sender could not be created for this track.");
 | 
| +    return nullptr;
 | 
| +  }
 | 
| +
 | 
| +  uintptr_t id = web_rtp_sender->Id();
 | 
| +  DCHECK(rtp_senders_.find(id) == rtp_senders_.end());
 | 
| +  RTCRtpSender* rtp_sender = new RTCRtpSender(std::move(web_rtp_sender), track);
 | 
| +  tracks_.insert(track->Component(), track);
 | 
| +  rtp_senders_.insert(id, rtp_sender);
 | 
| +  return rtp_sender;
 | 
| +}
 | 
| +
 | 
| +void RTCPeerConnection::removeTrack(RTCRtpSender* sender,
 | 
| +                                    ExceptionState& exception_state) {
 | 
| +  DCHECK(sender);
 | 
| +  if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state))
 | 
| +    return;
 | 
| +  if (rtp_senders_.find(sender->web_rtp_sender()->Id()) == rtp_senders_.end()) {
 | 
| +    exception_state.ThrowDOMException(
 | 
| +        kInvalidAccessError,
 | 
| +        "The sender was not created by this peer connection.");
 | 
| +  }
 | 
| +
 | 
| +  if (!peer_handler_->RemoveTrack(sender->web_rtp_sender())) {
 | 
| +    // Operation aborted. This indicates that the sender is no longer used by
 | 
| +    // the peer connection, i.e. that it was removed due to setting a remote
 | 
| +    // description of type "rollback".
 | 
| +    // Note: Until the WebRTC library supports re-using senders, a sender will
 | 
| +    // also stop being used as a result of being removed.
 | 
| +    return;
 | 
| +  }
 | 
| +  // Successfully removing the track results in the sender's track property
 | 
| +  // being nulled.
 | 
| +  DCHECK(!sender->web_rtp_sender()->Track());
 | 
| +  sender->SetTrack(nullptr);
 | 
| +}
 | 
| +
 | 
|  RTCDataChannel* RTCPeerConnection::createDataChannel(
 | 
|      ScriptState* script_state,
 | 
|      String label,
 | 
| 
 |