<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[235809] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/235809">235809</a></dd>
<dt>Author</dt> <dd>youenn@apple.com</dd>
<dt>Date</dt> <dd>2018-09-07 14:57:47 -0700 (Fri, 07 Sep 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for unified plan transceivers
https://bugs.webkit.org/show_bug.cgi?id=189390

Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

* web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt:
* web-platform-tests/webrtc/RTCPeerConnection-addTrack.https-expected.txt:
Regression comes from the fact that the sender was never used but transceiver direction is sendrecv.
This might need further clarification in the spec or implementation of libwebrtc.
* web-platform-tests/webrtc/RTCPeerConnection-addTransceiver-expected.txt:
* web-platform-tests/webrtc/RTCPeerConnection-removeTrack.https-expected.txt:
* web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt:
* web-platform-tests/webrtc/RTCRtpTransceiver-setDirection-expected.txt:

Source/ThirdParty/libwebrtc:

Expose more symbols.
* Configurations/libwebrtc.iOS.exp:
* Configurations/libwebrtc.iOSsim.exp:
* Configurations/libwebrtc.mac.exp:

Source/WebCore:

Keep previous transceiver behavior when unified plan flag is off.
Otherwise, use the libwebrtc transceiver API to create and use unified plan transceivers.
Fuel the implementation of transceivers through a dedicated backend.

Update transceiver IDL and make some smaller fixes at the same time:
- Make sure remote sources have a proper name as per https://w3c.github.io/webrtc-pc/#dfn-create-an-rtcrtpreceiver.
- Add support for transceiver.currentDirection.

Our mock peer connections are only supporting plan B APIs at the moment.
We therefore mandate plan B when using such mocks until we can upgrade mocks to support unified plan APIs.

Covered by modified and rebased tests.

* Modules/mediastream/PeerConnectionBackend.cpp:
(WebCore::PeerConnectionBackend::addTrack):
* Modules/mediastream/PeerConnectionBackend.h:
* Modules/mediastream/RTCPeerConnection.cpp:
(WebCore::RTCPeerConnection::addTrack):
(WebCore::RTCPeerConnection::addTransceiver):
* Modules/mediastream/RTCRtpSender.cpp:
(WebCore::RTCRtpSender::RTCRtpSender):
* Modules/mediastream/RTCRtpTransceiver.cpp:
(WebCore::RTCRtpTransceiver::mid const):
(WebCore::RTCRtpTransceiver::currentDirection const):
* Modules/mediastream/RTCRtpTransceiver.h:
(WebCore::RTCRtpTransceiver::backend):
* Modules/mediastream/RTCRtpTransceiver.idl:
* Modules/mediastream/RTCRtpTransceiverBackend.h:
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::LibWebRTCMediaEndpoint::addTrack):
(WebCore::LibWebRTCMediaEndpoint::newTransceiver):
(WebCore::LibWebRTCMediaEndpoint::addTransceiver):
(WebCore::LibWebRTCMediaEndpoint::transceiverBackendFromSender):
(WebCore::LibWebRTCMediaEndpoint::OnAddTrack):
(WebCore::LibWebRTCMediaEndpoint::OnTrack):
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h:
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
(WebCore::createReceiverForSource):
(WebCore::LibWebRTCPeerConnectionBackend::createReceiver):
(WebCore::LibWebRTCPeerConnectionBackend::videoReceiver):
(WebCore::LibWebRTCPeerConnectionBackend::audioReceiver):
(WebCore::LibWebRTCPeerConnectionBackend::addTrack):
(WebCore::LibWebRTCPeerConnectionBackend::addTransceiver):
(WebCore::backendFromRTPTransceiver):
(WebCore::LibWebRTCPeerConnectionBackend::existingTransceiver):
(WebCore::LibWebRTCPeerConnectionBackend::newTransceiver):
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
* Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp:
(WebCore::LibWebRTCRtpSenderBackend::replaceTrack):
* Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h:
* Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp: Added.
(WebCore::LibWebRTCRtpTransceiverBackend::createReceiverBackend):
(WebCore::LibWebRTCRtpTransceiverBackend::createSenderBackend):
(WebCore::LibWebRTCRtpTransceiverBackend::direction const):
(WebCore::LibWebRTCRtpTransceiverBackend::currentDirection const):
(WebCore::LibWebRTCRtpTransceiverBackend::setDirection):
(WebCore::LibWebRTCRtpTransceiverBackend::mid):
(WebCore::LibWebRTCRtpTransceiverBackend::stop):
* Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.h: Added.
* Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp:
(WebCore::toRTCRtpTransceiverDirection):
(WebCore::fromRTCRtpTransceiverDirection):
(WebCore::fromRtpTransceiverInit):
* Modules/mediastream/libwebrtc/LibWebRTCUtils.h:
* WebCore.xcodeproj/project.pbxproj:
* platform/mediastream/RealtimeIncomingAudioSource.cpp:
(WebCore::RealtimeIncomingAudioSource::RealtimeIncomingAudioSource):
* platform/mediastream/RealtimeIncomingVideoSource.cpp:
(WebCore::RealtimeIncomingVideoSource::RealtimeIncomingVideoSource):
* platform/mediastream/RealtimeMediaSource.h:
* testing/Internals.cpp:
(WebCore::Internals::useMockRTCPeerConnectionFactory):

LayoutTests:

Update tests using mock to enforce plan B for now until unified plan mocks are supported.

* fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt:
* fast/mediastream/RTCPeerConnection-icecandidate-event.html:
* fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html:
* fast/mediastream/RTCPeerConnection-inspect-answer.html:
* fast/mediastream/RTCPeerConnection-inspect-offer.html:
* fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html:
* fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html:
* fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html:
* fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html:
* fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html:
* webrtc/calling-peerconnection-once-closed.html:
Once closed, addTransceiver is expected to throw.
* webrtc/libwebrtc/release-while-creating-offer.html:
* webrtc/libwebrtc/release-while-getting-stats.html:
* webrtc/libwebrtc/release-while-setting-local-description.html:
* webrtc/video-getParameters.html: sender and receiver parameters are no longer the same.
Testing them individually.
* webrtc/video-with-receiver.html:
Test is working only with legacy mode.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionaddIceCandidateexpectedtxt">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionicecandidateeventhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectioniceconnectionstatechangeeventhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectioninspectanswerhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-answer.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectioninspectofferhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionmediasetupsingledialoghtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionmediasetuptwodialogshtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionremotelyassignedtransceivermidhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionsetLocalDescriptionofferhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionsetRemoteDescriptionofferhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCDTMFSenderinsertDTMFhttpsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionaddTrackhttpsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTrack.https-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionaddTransceiverexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTransceiver-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectiononnegotiationneededexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionremoveTrackhttpsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-removeTrack.https-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionsetDescriptiontransceiverexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCRtpTransceiversetDirectionexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpTransceiver-setDirection-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebrtccallingpeerconnectiononceclosedhtml">trunk/LayoutTests/webrtc/calling-peerconnection-once-closed.html</a></li>
<li><a href="#trunkLayoutTestswebrtclibwebrtcreleasewhilecreatingofferhtml">trunk/LayoutTests/webrtc/libwebrtc/release-while-creating-offer.html</a></li>
<li><a href="#trunkLayoutTestswebrtclibwebrtcreleasewhilegettingstatshtml">trunk/LayoutTests/webrtc/libwebrtc/release-while-getting-stats.html</a></li>
<li><a href="#trunkLayoutTestswebrtclibwebrtcreleasewhilesettinglocaldescriptionhtml">trunk/LayoutTests/webrtc/libwebrtc/release-while-setting-local-description.html</a></li>
<li><a href="#trunkLayoutTestswebrtcvideogetParametershtml">trunk/LayoutTests/webrtc/video-getParameters.html</a></li>
<li><a href="#trunkLayoutTestswebrtcvideowithreceiverhtml">trunk/LayoutTests/webrtc/video-with-receiver.html</a></li>
<li><a href="#trunkSourceThirdPartylibwebrtcChangeLog">trunk/Source/ThirdParty/libwebrtc/ChangeLog</a></li>
<li><a href="#trunkSourceThirdPartylibwebrtcConfigurationslibwebrtciOSexp">trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp</a></li>
<li><a href="#trunkSourceThirdPartylibwebrtcConfigurationslibwebrtciOSsimexp">trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp</a></li>
<li><a href="#trunkSourceThirdPartylibwebrtcConfigurationslibwebrtcmacexp">trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamPeerConnectionBackendcpp">trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamPeerConnectionBackendh">trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCPeerConnectioncpp">trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCRtpReceiverh">trunk/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCRtpSendercpp">trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCRtpTransceivercpp">trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCRtpTransceiverh">trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCRtpTransceiveridl">trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCRtpTransceiverBackendh">trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiverBackend.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointh">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendcpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendh">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpSenderBackendcpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpSenderBackendh">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCUtilscpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCUtilsh">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeIncomingAudioSourcecpp">trunk/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeIncomingVideoSourcecpp">trunk/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpTransceiverBackendcpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpTransceiverBackendh">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/ChangeLog 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2018-09-07  Youenn Fablet  <youenn@apple.com>
+
+        Add support for unified plan transceivers
+        https://bugs.webkit.org/show_bug.cgi?id=189390
+
+        Reviewed by Eric Carlson.
+
+        Update tests using mock to enforce plan B for now until unified plan mocks are supported.
+
+        * fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt:
+        * fast/mediastream/RTCPeerConnection-icecandidate-event.html:
+        * fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html:
+        * fast/mediastream/RTCPeerConnection-inspect-answer.html:
+        * fast/mediastream/RTCPeerConnection-inspect-offer.html:
+        * fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html:
+        * fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html:
+        * fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html:
+        * fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html:
+        * fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html:
+        * webrtc/calling-peerconnection-once-closed.html:
+        Once closed, addTransceiver is expected to throw.
+        * webrtc/libwebrtc/release-while-creating-offer.html:
+        * webrtc/libwebrtc/release-while-getting-stats.html:
+        * webrtc/libwebrtc/release-while-setting-local-description.html:
+        * webrtc/video-getParameters.html: sender and receiver parameters are no longer the same.
+        Testing them individually.
+        * webrtc/video-with-receiver.html:
+        Test is working only with legacy mode.
+
</ins><span class="cx"> 2018-09-07  Frederic Wang  <fwang@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [CSSOM View] Handle the scrollingElement in Element::scroll(Left/Top/Width/Height/To)
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionaddIceCandidateexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -11,7 +11,7 @@
</span><span class="cx"> 
</span><span class="cx"> *** Define sdpMid, badSdpMid, sdpMLineIndex and badSdpMLineIndex for testing
</span><span class="cx"> PASS sdpMLineIndex is not badSdpMLineIndex
</span><del>-FAIL sdpMid should not be null.
</del><ins>+PASS sdpMid is not null
</ins><span class="cx"> PASS sdpMid is not badSdpMid
</span><span class="cx"> FAIL promise pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMid: badSdpMid})) fulfilled unexpectedly.
</span><span class="cx"> FAIL promise pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMLineIndex: badSdpMLineIndex})) fulfilled unexpectedly.
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionicecandidateeventhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html     2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html        2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -8,6 +8,9 @@
</span><span class="cx">         <script>
</span><span class="cx">             description("Test RTCPeerConnection 'icecandidate' event and gathering done");
</span><span class="cx"> 
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("ICECandidates");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectioniceconnectionstatechangeeventhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html 2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html    2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -7,6 +7,8 @@
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><span class="cx">             description("Test RTCPeerConnection 'iceconnectionstatechange' event");
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
</ins><span class="cx"> 
</span><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("ICEConnectionState");
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectioninspectanswerhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-answer.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-answer.html 2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-answer.html    2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -6,6 +6,9 @@
</span><span class="cx">     </head>
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectioninspectofferhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html  2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html     2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -6,6 +6,9 @@
</span><span class="cx">     </head>
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionmediasetupsingledialoghtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -6,6 +6,9 @@
</span><span class="cx">     </head>
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionmediasetuptwodialogshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -11,9 +11,10 @@
</span><span class="cx"> 
</span><span class="cx">             description("Test setting up media between two RTCPeerConnection instances with a single SDP dialog.");
</span><span class="cx"> 
</span><del>-            if (window.testRunner)
</del><ins>+            if (window.testRunner) {
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
</ins><span class="cx">                 testRunner.setUserMediaPermission(true);
</span><del>-            else {
</del><ins>+            } else {
</ins><span class="cx">                 debug("This test can not be run without the testRunner");
</span><span class="cx">                 finishJSTest();
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionremotelyassignedtransceivermidhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -6,6 +6,9 @@
</span><span class="cx">     </head>
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionsetLocalDescriptionofferhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -6,6 +6,9 @@
</span><span class="cx">     </head>
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionsetRemoteDescriptionofferhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html     2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html        2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -6,6 +6,9 @@
</span><span class="cx">     </head>
</span><span class="cx">     <body>
</span><span class="cx">         <script>
</span><ins>+            if (window.testRunner)
+                testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx">             if (window.internals)
</span><span class="cx">                 internals.useMockRTCPeerConnectionFactory("");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog 2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/ChangeLog    2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2018-09-07  Youenn Fablet  <youenn@apple.com>
+
+        Add support for unified plan transceivers
+        https://bugs.webkit.org/show_bug.cgi?id=189390
+
+        Reviewed by Eric Carlson.
+
+        * web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt:
+        * web-platform-tests/webrtc/RTCPeerConnection-addTrack.https-expected.txt:
+        Regression comes from the fact that the sender was never used but transceiver direction is sendrecv.
+        This might need further clarification in the spec or implementation of libwebrtc.
+        * web-platform-tests/webrtc/RTCPeerConnection-addTransceiver-expected.txt:
+        * web-platform-tests/webrtc/RTCPeerConnection-removeTrack.https-expected.txt:
+        * web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt:
+        * web-platform-tests/webrtc/RTCRtpTransceiver-setDirection-expected.txt:
+
</ins><span class="cx"> 2018-09-07  Rob Buis  <rbuis@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         XMLHttpRequest: open() does not throw a SYNTAX_ERR exception if method is empty or url cannot be resolved
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCDTMFSenderinsertDTMFhttpsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt     2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCDTMFSender-insertDTMF.https-expected.txt        2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -2,8 +2,8 @@
</span><span class="cx"> FAIL insertDTMF() should succeed if tones contains valid DTMF characters promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: RTCDTMFSender"
</span><span class="cx"> FAIL insertDTMF() should throw InvalidCharacterError if tones contains invalid DTMF characters promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: RTCDTMFSender"
</span><span class="cx"> FAIL insertDTMF() should throw InvalidStateError if transceiver is stopped assert_throws: function "() => dtmfSender.insertDTMF('')" threw object "TypeError: undefined is not an object (evaluating 'dtmfSender.insertDTMF')" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
</span><del>-FAIL insertDTMF() should throw InvalidStateError if transceiver.currentDirection is recvonly assert_equals: expected (string) "inactive" but got (undefined) undefined
-FAIL insertDTMF() should throw InvalidStateError if transceiver.currentDirection is inactive assert_equals: expected (string) "inactive" but got (undefined) undefined
</del><ins>+FAIL insertDTMF() should throw InvalidStateError if transceiver.currentDirection is recvonly assert_equals: expected (string) "inactive" but got (object) null
+FAIL insertDTMF() should throw InvalidStateError if transceiver.currentDirection is inactive assert_equals: expected (string) "inactive" but got (object) null
</ins><span class="cx"> FAIL insertDTMF() should set toneBuffer to provided tones normalized, with old tones overridden promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: RTCDTMFSender"
</span><span class="cx"> FAIL insertDTMF() after remove and close should reject assert_throws: function "() =>
</span><span class="cx">                       dtmfSender.insertDTMF('123')" threw object "TypeError: undefined is not an object (evaluating 'dtmfSender.insertDTMF')" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionaddTrackhttpsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTrack.https-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTrack.https-expected.txt   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTrack.https-expected.txt      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -5,6 +5,6 @@
</span><span class="cx"> PASS addTrack with single track argument and multiple mediaStreams should succeed 
</span><span class="cx"> PASS Adding the same track multiple times should throw InvalidAccessError 
</span><span class="cx"> PASS addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender 
</span><del>-PASS addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender 
</del><ins>+FAIL addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender assert_not_equals: got disallowed value object "[object RTCRtpSender]"
</ins><span class="cx"> PASS addTrack with existing sender with null track, different kind, and recvonly direction should create new sender 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionaddTransceiverexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTransceiver-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTransceiver-expected.txt   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-addTransceiver-expected.txt      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,11 +1,11 @@
</span><span class="cx"> 
</span><span class="cx"> PASS addTransceiver() with string argument as invalid kind should throw TypeError 
</span><del>-FAIL addTransceiver('audio') should return an audio transceiver assert_equals: expected (object) null but got (undefined) undefined
-FAIL addTransceiver('video') should return a video transceiver assert_equals: expected "remote video" but got ""
</del><ins>+PASS addTransceiver('audio') should return an audio transceiver 
+PASS addTransceiver('video') should return a video transceiver 
</ins><span class="cx"> PASS addTransceiver() with direction sendonly should have result transceiver.direction be the same 
</span><span class="cx"> PASS addTransceiver() with direction inactive should have result transceiver.direction be the same 
</span><span class="cx"> PASS addTransceiver() with invalid direction should throw TypeError 
</span><del>-FAIL addTransceiver(track) should have result with sender.track be given track assert_equals: expected "remote audio" but got ""
</del><ins>+PASS addTransceiver(track) should have result with sender.track be given track 
</ins><span class="cx"> PASS addTransceiver(track) multiple times should create multiple transceivers 
</span><span class="cx"> FAIL addTransceiver() with rid containing invalid non-alphanumeric characters should throw TypeError assert_throws: function "() =>
</span><span class="cx">       pc.addTransceiver('audio', {
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectiononnegotiationneededexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -3,9 +3,9 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Creating first data channel should fire negotiationneeded event 
</span><span class="cx"> PASS calling createDataChannel twice should fire negotiationneeded event once 
</span><del>-TIMEOUT addTransceiver() should fire negotiationneeded event Test timed out
-PASS Calling addTransceiver() twice should fire negotiationneeded event once 
-PASS Calling both addTransceiver() and createDataChannel() should fire negotiationneeded event once 
</del><ins>+PASS addTransceiver() should fire negotiationneeded event 
+FAIL Calling addTransceiver() twice should fire negotiationneeded event once assert_unreached: Pending promise should never be resolved. Instead it is fulfilled with: [object Object] Reached unreachable code
+FAIL Calling both addTransceiver() and createDataChannel() should fire negotiationneeded event once assert_unreached: Pending promise should never be resolved. Instead it is fulfilled with: [object Object] Reached unreachable code
</ins><span class="cx"> PASS negotiationneeded event should not fire if signaling state is not stable 
</span><del>-NOTRUN negotiationneeded event should fire only after signaling state go back to stable 
</del><ins>+TIMEOUT negotiationneeded event should fire only after signaling state go back to stable Test timed out
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionremoveTrackhttpsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-removeTrack.https-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-removeTrack.https-expected.txt        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-removeTrack.https-expected.txt   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -5,10 +5,10 @@
</span><span class="cx"> PASS addTrack - Calling removeTrack on different connection that is closed should throw InvalidStateError 
</span><span class="cx"> FAIL addTransceiver - Calling removeTrack on different connection should throw InvalidAccessError assert_throws: function "() => pc2.removeTrack(sender)" did not throw
</span><span class="cx"> FAIL addTrack - Calling removeTrack on different connection should throw InvalidAccessError assert_throws: function "() => pc2.removeTrack(sender)" did not throw
</span><del>-FAIL addTransceiver - Calling removeTrack with valid sender should set sender.track to null assert_equals: expected (object) null but got (undefined) undefined
</del><ins>+FAIL addTransceiver - Calling removeTrack with valid sender should set sender.track to null assert_equals: direction should not be altered expected "sendrecv" but got "recvonly"
</ins><span class="cx"> PASS addTrack - Calling removeTrack with valid sender should set sender.track to null 
</span><del>-FAIL Calling removeTrack with currentDirection sendrecv should set direction to recvonly assert_equals: expected (object) null but got (undefined) undefined
-FAIL Calling removeTrack with currentDirection sendonly should set direction to inactive assert_equals: expected (object) null but got (undefined) undefined
-FAIL Calling removeTrack with currentDirection recvonly should not change direction assert_equals: expected (object) null but got (undefined) undefined
-FAIL Calling removeTrack with currentDirection inactive should not change direction assert_equals: expected (object) null but got (undefined) undefined
</del><ins>+FAIL Calling removeTrack with currentDirection sendrecv should set direction to recvonly assert_equals: expected "sendrecv" but got "sendonly"
+PASS Calling removeTrack with currentDirection sendonly should set direction to inactive 
+FAIL Calling removeTrack with currentDirection recvonly should not change direction assert_equals: expected "recvonly" but got "inactive"
+PASS Calling removeTrack with currentDirection inactive should not change direction 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionsetDescriptiontransceiverexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt       2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt  2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> 
</span><del>-FAIL setLocalDescription(offer) with m= section should assign mid to corresponding transceiver assert_equals: Expect transceiver.mid to set to valid string value expected "string" but got "object"
</del><ins>+PASS setLocalDescription(offer) with m= section should assign mid to corresponding transceiver 
</ins><span class="cx"> FAIL setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver promise_test: Unhandled rejection with value: object "TypeError: pc2.setRemoteDescrption is not a function. (In 'pc2.setRemoteDescrption(offer)', 'pc2.setRemoteDescrption' is undefined)"
</span><del>-FAIL setLocalDescription(rollback) should unset transceiver.mid assert_not_equals: got disallowed value null
-FAIL setLocalDescription(rollback) should only unset transceiver mids associated with current round assert_not_equals: got disallowed value null
-FAIL setRemoteDescription(rollback) should remove newly created transceiver from transceiver list assert_equals: expected 1 but got 0
</del><ins>+FAIL setLocalDescription(rollback) should unset transceiver.mid promise_test: Unhandled rejection with value: object "InvalidStateError: Description type incompatible with current signaling state"
+FAIL setLocalDescription(rollback) should only unset transceiver mids associated with current round promise_test: Unhandled rejection with value: object "InvalidStateError: Description type incompatible with current signaling state"
+FAIL setRemoteDescription(rollback) should remove newly created transceiver from transceiver list promise_test: Unhandled rejection with value: object "InvalidStateError: Description type incompatible with current signaling state"
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCRtpTransceiversetDirectionexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpTransceiver-setDirection-expected.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpTransceiver-setDirection-expected.txt     2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpTransceiver-setDirection-expected.txt        2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> 
</span><del>-FAIL setDirection should change transceiver.direction assert_equals: expected (object) null but got (undefined) undefined
</del><ins>+PASS setDirection should change transceiver.direction 
</ins><span class="cx"> PASS setDirection with same direction should have no effect 
</span><del>-FAIL setDirection should change transceiver.direction independent of transceiver.currentDirection assert_equals: expected (object) null but got (undefined) undefined
</del><ins>+FAIL setDirection should change transceiver.direction independent of transceiver.currentDirection assert_equals: expected "recvonly" but got "inactive"
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebrtccallingpeerconnectiononceclosedhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/calling-peerconnection-once-closed.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/calling-peerconnection-once-closed.html 2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/webrtc/calling-peerconnection-once-closed.html    2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> 
</span><span class="cx"> promise_test(() => {
</span><span class="cx">     return closedConnection().then((connection) => {
</span><del>-        connection.addTransceiver("video");
</del><ins>+        assert_throws("InvalidStateError", () => { connection.addTransceiver("video"); });
</ins><span class="cx">     });
</span><span class="cx"> }, "Ensuring closed connection addTransceiver does not crash");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebrtclibwebrtcreleasewhilecreatingofferhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/libwebrtc/release-while-creating-offer.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/libwebrtc/release-while-creating-offer.html     2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/webrtc/libwebrtc/release-while-creating-offer.html        2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -7,6 +7,9 @@
</span><span class="cx"> <script>
</span><span class="cx"> self.jsTestIsAsync = true;
</span><span class="cx"> 
</span><ins>+if (window.testRunner)
+    testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx"> if (window.internals)
</span><span class="cx">     internals.useMockRTCPeerConnectionFactory("LibWebRTCReleasingWhileCreatingOffer");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebrtclibwebrtcreleasewhilegettingstatshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/libwebrtc/release-while-getting-stats.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/libwebrtc/release-while-getting-stats.html      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/webrtc/libwebrtc/release-while-getting-stats.html 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -7,6 +7,9 @@
</span><span class="cx"> <script>
</span><span class="cx"> self.jsTestIsAsync = true;
</span><span class="cx"> 
</span><ins>+if (window.testRunner)
+    testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx"> if (window.internals)
</span><span class="cx">     internals.useMockRTCPeerConnectionFactory("LibWebRTCReleasingWhileGettingStats");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebrtclibwebrtcreleasewhilesettinglocaldescriptionhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/libwebrtc/release-while-setting-local-description.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/libwebrtc/release-while-setting-local-description.html  2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/webrtc/libwebrtc/release-while-setting-local-description.html     2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -10,6 +10,9 @@
</span><span class="cx"> // Silence unhandled rejection messages.
</span><span class="cx"> window.onunhandledrejection = () => false;
</span><span class="cx"> 
</span><ins>+if (window.testRunner)
+    testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx"> if (window.internals)
</span><span class="cx">     internals.useMockRTCPeerConnectionFactory("LibWebRTCReleasingWhileSettingDescription");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebrtcvideogetParametershtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/video-getParameters.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/video-getParameters.html        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/webrtc/video-getParameters.html   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -42,16 +42,13 @@
</span><span class="cx"> 
</span><span class="cx">         senderParameters.encodings[0].fec.ssrc = 1;
</span><span class="cx">         senderParameters.encodings[0].rtx.ssrc = 1;
</span><del>-        receiverParameters.encodings[0].fec.ssrc = 1;
-        receiverParameters.encodings[0].rtx.ssrc = 1;
</del><span class="cx"> 
</span><span class="cx">         senderParameters.transactionId = "";
</span><span class="cx">         receiverParameters.transactionId = "";
</span><span class="cx"> 
</span><del>-        assert_equals(JSON.stringify(senderParameters), JSON.stringify(receiverParameters), "testing sender vs. receiver parameters");
-
</del><span class="cx">         senderParameters.encodings[0].ssrc = 1;
</span><del>-        assert_equals(JSON.stringify(senderParameters), '{"codecs":[],"degradationPreference":"balanced","encodings":[{"active":true,"fec":{"ssrc":1},"maxBitrate":0,"maxFramerate":0,"priority":"medium","rid":"","rtx":{"ssrc":1},"scaleResolutionDownBy":1,"ssrc":1}],"headerExtensions":[],"transactionId":""}', "Testing sanitized parameters");
</del><ins>+        assert_equals(JSON.stringify(senderParameters), '{"codecs":[],"degradationPreference":"balanced","encodings":[{"active":true,"fec":{"ssrc":1},"maxBitrate":0,"maxFramerate":0,"priority":"medium","rid":"","rtx":{"ssrc":1},"scaleResolutionDownBy":1,"ssrc":1}],"headerExtensions":[],"transactionId":""}', "Testing sanitized sender parameters");
+        assert_equals(JSON.stringify(receiverParameters), '{"codecs":[],"degradationPreference":"balanced","encodings":[],"headerExtensions":[],"transactionId":""}', "Testing sanitized receiver parameters");
</ins><span class="cx">     });
</span><span class="cx"> }, "Basic video stats");
</span><span class="cx">         </script>
</span></span></pre></div>
<a id="trunkLayoutTestswebrtcvideowithreceiverhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/video-with-receiver.html (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/video-with-receiver.html        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/LayoutTests/webrtc/video-with-receiver.html   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -14,6 +14,9 @@
</span><span class="cx"> video = document.getElementById("video");
</span><span class="cx"> canvas = document.getElementById("canvas");
</span><span class="cx"> 
</span><ins>+if (window.testRunner)
+    testRunner.setWebRTCUnifiedPlanEnabled(false);
+
</ins><span class="cx"> function testImage()
</span><span class="cx"> {
</span><span class="cx">     canvas.width = video.videoWidth;
</span></span></pre></div>
<a id="trunkSourceThirdPartylibwebrtcChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/libwebrtc/ChangeLog      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2018-09-07  Youenn Fablet  <youenn@apple.com>
+
+        Add support for unified plan transceivers
+        https://bugs.webkit.org/show_bug.cgi?id=189390
+
+        Reviewed by Eric Carlson.
+
+        Expose more symbols.
+        * Configurations/libwebrtc.iOS.exp:
+        * Configurations/libwebrtc.iOSsim.exp:
+        * Configurations/libwebrtc.mac.exp:
+
</ins><span class="cx"> 2018-09-05  Youenn Fablet  <youenn@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Expose RTCRtpSender.setParameters
</span></span></pre></div>
<a id="trunkSourceThirdPartylibwebrtcConfigurationslibwebrtciOSexp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp       2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp  2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -212,3 +212,5 @@
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersC1ERKS0_
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersC1Ev
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersD1Ev
</span><ins>+__ZN6webrtc18RtpTransceiverInitC1Ev
+__ZN6webrtc18RtpTransceiverInitD1Ev
</ins></span></pre></div>
<a id="trunkSourceThirdPartylibwebrtcConfigurationslibwebrtciOSsimexp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp    2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp       2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -213,3 +213,6 @@
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersC1ERKS0_
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersC1Ev
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersD1Ev
</span><ins>+
+__ZN6webrtc18RtpTransceiverInitC1Ev
+__ZN6webrtc18RtpTransceiverInitD1Ev
</ins></span></pre></div>
<a id="trunkSourceThirdPartylibwebrtcConfigurationslibwebrtcmacexp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp       2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp  2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -213,3 +213,5 @@
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersC1ERKS0_
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersC1Ev
</span><span class="cx"> __ZN6webrtc21RtpEncodingParametersD1Ev
</span><ins>+__ZN6webrtc18RtpTransceiverInitC1Ev
+__ZN6webrtc18RtpTransceiverInitD1Ev
</ins></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/CMakeLists.txt 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1572,6 +1572,7 @@
</span><span class="cx">       Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp
</span><span class="cx">       Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverBackend.cpp
</span><span class="cx">       Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp
</span><ins>+      Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp
</ins><span class="cx">       Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp
</span><span class="cx">       )
</span><span class="cx"> endif ()
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/ChangeLog      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2018-09-07  Youenn Fablet  <youenn@apple.com>
+
+        Add support for unified plan transceivers
+        https://bugs.webkit.org/show_bug.cgi?id=189390
+
+        Reviewed by Eric Carlson.
+
+        Keep previous transceiver behavior when unified plan flag is off.
+        Otherwise, use the libwebrtc transceiver API to create and use unified plan transceivers.
+        Fuel the implementation of transceivers through a dedicated backend.
+
+        Update transceiver IDL and make some smaller fixes at the same time:
+        - Make sure remote sources have a proper name as per https://w3c.github.io/webrtc-pc/#dfn-create-an-rtcrtpreceiver.
+        - Add support for transceiver.currentDirection.
+
+        Our mock peer connections are only supporting plan B APIs at the moment.
+        We therefore mandate plan B when using such mocks until we can upgrade mocks to support unified plan APIs.
+
+        Covered by modified and rebased tests.
+
+        * Modules/mediastream/PeerConnectionBackend.cpp:
+        (WebCore::PeerConnectionBackend::addTrack):
+        * Modules/mediastream/PeerConnectionBackend.h:
+        * Modules/mediastream/RTCPeerConnection.cpp:
+        (WebCore::RTCPeerConnection::addTrack):
+        (WebCore::RTCPeerConnection::addTransceiver):
+        * Modules/mediastream/RTCRtpSender.cpp:
+        (WebCore::RTCRtpSender::RTCRtpSender):
+        * Modules/mediastream/RTCRtpTransceiver.cpp:
+        (WebCore::RTCRtpTransceiver::mid const):
+        (WebCore::RTCRtpTransceiver::currentDirection const):
+        * Modules/mediastream/RTCRtpTransceiver.h:
+        (WebCore::RTCRtpTransceiver::backend):
+        * Modules/mediastream/RTCRtpTransceiver.idl:
+        * Modules/mediastream/RTCRtpTransceiverBackend.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+        (WebCore::LibWebRTCMediaEndpoint::addTrack):
+        (WebCore::LibWebRTCMediaEndpoint::newTransceiver):
+        (WebCore::LibWebRTCMediaEndpoint::addTransceiver):
+        (WebCore::LibWebRTCMediaEndpoint::transceiverBackendFromSender):
+        (WebCore::LibWebRTCMediaEndpoint::OnAddTrack):
+        (WebCore::LibWebRTCMediaEndpoint::OnTrack):
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
+        (WebCore::createReceiverForSource):
+        (WebCore::LibWebRTCPeerConnectionBackend::createReceiver):
+        (WebCore::LibWebRTCPeerConnectionBackend::videoReceiver):
+        (WebCore::LibWebRTCPeerConnectionBackend::audioReceiver):
+        (WebCore::LibWebRTCPeerConnectionBackend::addTrack):
+        (WebCore::LibWebRTCPeerConnectionBackend::addTransceiver):
+        (WebCore::backendFromRTPTransceiver):
+        (WebCore::LibWebRTCPeerConnectionBackend::existingTransceiver):
+        (WebCore::LibWebRTCPeerConnectionBackend::newTransceiver):
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp:
+        (WebCore::LibWebRTCRtpSenderBackend::replaceTrack):
+        * Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp: Added.
+        (WebCore::LibWebRTCRtpTransceiverBackend::createReceiverBackend):
+        (WebCore::LibWebRTCRtpTransceiverBackend::createSenderBackend):
+        (WebCore::LibWebRTCRtpTransceiverBackend::direction const):
+        (WebCore::LibWebRTCRtpTransceiverBackend::currentDirection const):
+        (WebCore::LibWebRTCRtpTransceiverBackend::setDirection):
+        (WebCore::LibWebRTCRtpTransceiverBackend::mid):
+        (WebCore::LibWebRTCRtpTransceiverBackend::stop):
+        * Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.h: Added.
+        * Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp:
+        (WebCore::toRTCRtpTransceiverDirection):
+        (WebCore::fromRTCRtpTransceiverDirection):
+        (WebCore::fromRtpTransceiverInit):
+        * Modules/mediastream/libwebrtc/LibWebRTCUtils.h:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/mediastream/RealtimeIncomingAudioSource.cpp:
+        (WebCore::RealtimeIncomingAudioSource::RealtimeIncomingAudioSource):
+        * platform/mediastream/RealtimeIncomingVideoSource.cpp:
+        (WebCore::RealtimeIncomingVideoSource::RealtimeIncomingVideoSource):
+        * platform/mediastream/RealtimeMediaSource.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::useMockRTCPeerConnectionFactory):
+
</ins><span class="cx"> 2018-09-07  Rob Buis  <rbuis@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         XMLHttpRequest: open() does not throw a SYNTAX_ERR exception if method is empty or url cannot be resolved
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamPeerConnectionBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp       2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp  2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -530,7 +530,7 @@
</span><span class="cx">         m_peerConnection.scheduleNegotiationNeededEvent();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ExceptionOr<Ref<RTCRtpSender>> PeerConnectionBackend::addTrack(RTCRtpSender*, MediaStreamTrack&, const Vector<String>&)
</del><ins>+ExceptionOr<Ref<RTCRtpSender>> PeerConnectionBackend::addTrack(MediaStreamTrack&, Vector<String>&&)
</ins><span class="cx"> {
</span><span class="cx">     return Exception { NotSupportedError, "Not implemented"_s };
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamPeerConnectionBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h 2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h    2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -100,7 +100,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&) = 0;
</span><span class="cx"> 
</span><del>-    virtual ExceptionOr<Ref<RTCRtpSender>> addTrack(RTCRtpSender*, MediaStreamTrack&, const Vector<String>&);
</del><ins>+    virtual ExceptionOr<Ref<RTCRtpSender>> addTrack(MediaStreamTrack&, Vector<String>&&);
</ins><span class="cx">     virtual void removeTrack(RTCRtpSender&) { }
</span><span class="cx"> 
</span><span class="cx">     virtual ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(const String&, const RTCRtpTransceiverInit&);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCPeerConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -122,22 +122,7 @@
</span><span class="cx">     for (auto stream : streams)
</span><span class="cx">         mediaStreamIds.append(stream.get().id());
</span><span class="cx"> 
</span><del>-    RTCRtpSender* sender = nullptr;
-
-    // Reuse an existing sender with the same track kind if it has never been used to send before.
-    for (auto& transceiver : m_transceiverSet->list()) {
-        auto& existingSender = transceiver->sender();
-        if (existingSender.trackKind() == track->kind() && existingSender.trackId().isNull() && !transceiver->hasSendingDirection()) {
-            existingSender.setTrack(track.copyRef());
-            existingSender.setMediaStreamIds(WTFMove(mediaStreamIds));
-            transceiver->enableSendingDirection();
-            sender = &existingSender;
-            
-            break;
-        }
-    }
-
-    return m_backend->addTrack(sender, track.get(), mediaStreamIds);
</del><ins>+    return m_backend->addTrack(track.get(), WTFMove(mediaStreamIds));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ExceptionOr<void> RTCPeerConnection::removeTrack(RTCRtpSender& sender)
</span><span class="lines">@@ -168,12 +153,18 @@
</span><span class="cx"> 
</span><span class="cx">     if (WTF::holds_alternative<String>(withTrack)) {
</span><span class="cx">         const String& kind = WTF::get<String>(withTrack);
</span><del>-        if (kind != "audio" && kind != "video")
</del><ins>+        if (kind != "audio"_s && kind != "video"_s)
</ins><span class="cx">             return Exception { TypeError };
</span><span class="cx"> 
</span><ins>+        if (isClosed())
+            return Exception { InvalidStateError };
+
</ins><span class="cx">         return m_backend->addTransceiver(kind, init);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (isClosed())
+        return Exception { InvalidStateError };
+
</ins><span class="cx">     auto track = WTF::get<RefPtr<MediaStreamTrack>>(withTrack).releaseNonNull();
</span><span class="cx">     return m_backend->addTransceiver(WTFMove(track), init);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCRtpReceiverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> 
</span><span class="cx"> class RTCRtpReceiver : public RTCRtpSenderReceiverBase {
</span><span class="cx"> public:
</span><del>-    static Ref<RTCRtpReceiver> create(Ref<MediaStreamTrack>&& track, std::unique_ptr<RTCRtpReceiverBackend>&& backend = nullptr)
</del><ins>+    static Ref<RTCRtpReceiver> create(Ref<MediaStreamTrack>&& track, std::unique_ptr<RTCRtpReceiverBackend>&& backend)
</ins><span class="cx">     {
</span><span class="cx">         return adoptRef(*new RTCRtpReceiver(WTFMove(track), WTFMove(backend)));
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCRtpSendercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -33,6 +33,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEB_RTC)
</span><span class="cx"> 
</span><ins>+#include "RuntimeEnabledFeatures.h"
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> Ref<RTCRtpSender> RTCRtpSender::create(Ref<MediaStreamTrack>&& track, Vector<String>&& mediaStreamIds, std::unique_ptr<RTCRtpSenderBackend>&& backend)
</span><span class="lines">@@ -53,6 +55,7 @@
</span><span class="cx">     , m_mediaStreamIds(WTFMove(mediaStreamIds))
</span><span class="cx">     , m_backend(WTFMove(backend))
</span><span class="cx"> {
</span><ins>+    ASSERT(!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled() || m_backend);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RTCRtpSender::setTrackToNull()
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCRtpTransceivercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -47,11 +47,9 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const String& RTCRtpTransceiver::mid() const
</del><ins>+String RTCRtpTransceiver::mid() const
</ins><span class="cx"> {
</span><del>-    if (!m_backend)
-        return m_mid;
-    return m_backend->mid();
</del><ins>+    return m_backend ? m_backend->mid() : String { };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RTCRtpTransceiver::hasSendingDirection() const
</span><span class="lines">@@ -66,6 +64,13 @@
</span><span class="cx">     return m_backend->direction();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+std::optional<RTCRtpTransceiverDirection> RTCRtpTransceiver::currentDirection() const
+{
+    if (!m_backend)
+        return std::nullopt;
+    return m_backend->currentDirection();
+}
+
</ins><span class="cx"> void RTCRtpTransceiver::setDirection(RTCRtpTransceiverDirection direction)
</span><span class="cx"> {
</span><span class="cx">     m_direction = direction;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCRtpTransceiverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h     2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h        2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -55,8 +55,9 @@
</span><span class="cx">     void disableSendingDirection();
</span><span class="cx"> 
</span><span class="cx">     RTCRtpTransceiverDirection direction() const;
</span><ins>+    std::optional<RTCRtpTransceiverDirection> currentDirection() const;
</ins><span class="cx">     void setDirection(RTCRtpTransceiverDirection);
</span><del>-    const String& mid() const;
</del><ins>+    String mid() const;
</ins><span class="cx"> 
</span><span class="cx">     RTCRtpSender& sender() { return m_sender.get(); }
</span><span class="cx">     RTCRtpReceiver& receiver() { return m_receiver.get(); }
</span><span class="lines">@@ -69,10 +70,11 @@
</span><span class="cx">     // transport each.
</span><span class="cx">     RTCIceTransport& iceTransport() { return m_iceTransport.get(); }
</span><span class="cx"> 
</span><ins>+    RTCRtpTransceiverBackend* backend() { return m_backend.get(); }
+
</ins><span class="cx"> private:
</span><span class="cx">     RTCRtpTransceiver(Ref<RTCRtpSender>&&, Ref<RTCRtpReceiver>&&, std::unique_ptr<RTCRtpTransceiverBackend>&&);
</span><span class="cx"> 
</span><del>-    String m_mid;
</del><span class="cx">     RTCRtpTransceiverDirection m_direction;
</span><span class="cx"> 
</span><span class="cx">     Ref<RTCRtpSender> m_sender;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCRtpTransceiveridl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -36,13 +36,11 @@
</span><span class="cx">     EnabledAtRuntime=PeerConnection
</span><span class="cx"> ] interface RTCRtpTransceiver {
</span><span class="cx">     readonly attribute DOMString? mid;
</span><del>-    // FIXME 169662: missing [SameObject]
-    readonly attribute RTCRtpSender sender;
-    // FIXME 169662: missing [SameObject]
-    readonly attribute RTCRtpReceiver receiver;
</del><ins>+    [SameObject] readonly attribute RTCRtpSender sender;
+    [SameObject] readonly attribute RTCRtpReceiver receiver;
</ins><span class="cx">     readonly attribute boolean stopped;
</span><span class="cx">     readonly attribute RtpTransceiverDirection direction;
</span><del>-    // FIXME 169662: missing currentDirection
</del><ins>+    readonly attribute RTCRtpTransceiverDirection? currentDirection;
</ins><span class="cx">     void setDirection(RtpTransceiverDirection direction);
</span><span class="cx">     void stop();
</span><span class="cx">     // FIXME 169662: missing setCodecPreferences
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCRtpTransceiverBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiverBackend.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiverBackend.h      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiverBackend.h 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -35,9 +35,10 @@
</span><span class="cx">     virtual ~RTCRtpTransceiverBackend() = default;
</span><span class="cx"> 
</span><span class="cx">     virtual RTCRtpTransceiverDirection direction() const = 0;
</span><ins>+    virtual std::optional<RTCRtpTransceiverDirection> currentDirection() const = 0;
</ins><span class="cx">     virtual void setDirection(RTCRtpTransceiverDirection) = 0;
</span><span class="cx"> 
</span><del>-    virtual const String& mid() = 0;
</del><ins>+    virtual String mid() = 0;
</ins><span class="cx">     virtual void stop() = 0;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp    2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp       2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include "LibWebRTCProvider.h"
</span><span class="cx"> #include "LibWebRTCRtpReceiverBackend.h"
</span><span class="cx"> #include "LibWebRTCRtpSenderBackend.h"
</span><ins>+#include "LibWebRTCRtpTransceiverBackend.h"
</ins><span class="cx"> #include "LibWebRTCStatsCollector.h"
</span><span class="cx"> #include "LibWebRTCUtils.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="lines">@@ -197,7 +198,6 @@
</span><span class="cx"> bool LibWebRTCMediaEndpoint::addTrack(LibWebRTCRtpSenderBackend& sender, MediaStreamTrack& track, const Vector<String>& mediaStreamIds)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_backend);
</span><del>-    ASSERT(!sender.rtcSender());
</del><span class="cx"> 
</span><span class="cx">     if (!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled()) {
</span><span class="cx">         String mediaStreamId = mediaStreamIds.isEmpty() ? createCanonicalUUIDString() : mediaStreamIds[0];
</span><span class="lines">@@ -208,35 +208,41 @@
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    std::vector<std::string> ids;
-    for (auto& id : mediaStreamIds)
-        ids.push_back(id.utf8().data());
-
</del><ins>+    LibWebRTCRtpSenderBackend::Source source;
+    rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> rtcTrack;
</ins><span class="cx">     switch (track.privateTrack().type()) {
</span><span class="cx">     case RealtimeMediaSource::Type::Audio: {
</span><span class="cx">         auto audioSource = RealtimeOutgoingAudioSource::create(track.privateTrack());
</span><del>-        auto audioTrack = m_peerConnectionFactory.CreateAudioTrack(track.id().utf8().data(), audioSource.ptr());
-        sender.setSource(WTFMove(audioSource));
-        auto rtpSender = m_backend->AddTrack(audioTrack.get(), WTFMove(ids));
-        if (!rtpSender.ok())
-            return false;
-        sender.setRTCSender(rtpSender.MoveValue());
-        return true;
</del><ins>+        rtcTrack = m_peerConnectionFactory.CreateAudioTrack(track.id().utf8().data(), audioSource.ptr());
+        source = WTFMove(audioSource);
+        break;
</ins><span class="cx">     }
</span><span class="cx">     case RealtimeMediaSource::Type::Video: {
</span><span class="cx">         auto videoSource = RealtimeOutgoingVideoSource::create(track.privateTrack());
</span><del>-        auto videoTrack = m_peerConnectionFactory.CreateVideoTrack(track.id().utf8().data(), videoSource.ptr());
-        sender.setSource(WTFMove(videoSource));
-        auto rtpSender = m_backend->AddTrack(videoTrack.get(), WTFMove(ids));
-        if (!rtpSender.ok())
-            return false;
-        sender.setRTCSender(rtpSender.MoveValue());
-        return true;
</del><ins>+        rtcTrack = m_peerConnectionFactory.CreateVideoTrack(track.id().utf8().data(), videoSource.ptr());
+        source = WTFMove(videoSource);
+        break;
</ins><span class="cx">     }
</span><span class="cx">     case RealtimeMediaSource::Type::None:
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><ins>+        return false;
</ins><span class="cx">     }
</span><del>-    return false;
</del><ins>+
+    sender.setSource(WTFMove(source));
+    if (auto rtpSender = sender.rtcSender()) {
+        rtpSender->SetTrack(rtcTrack.get());
+        return true;
+    }
+
+    std::vector<std::string> ids;
+    for (auto& id : mediaStreamIds)
+        ids.push_back(id.utf8().data());
+
+    auto newRTPSender = m_backend->AddTrack(rtcTrack.get(), WTFMove(ids));
+    if (!newRTPSender.ok())
+        return false;
+    sender.setRTCSender(newRTPSender.MoveValue());
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void LibWebRTCMediaEndpoint::removeTrack(LibWebRTCRtpSenderBackend& sender)
</span><span class="lines">@@ -361,20 +367,131 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     receiver->setBackend(std::make_unique<LibWebRTCRtpReceiverBackend>(WTFMove(rtcReceiver)));
</span><del>-    
-    auto* track = receiver->track();
-    ASSERT(track);
</del><ins>+    auto& track = *receiver->track();
+    fireTrackEvent(receiver.releaseNonNull(), track, rtcStreams, nullptr);
+}
</ins><span class="cx"> 
</span><ins>+void LibWebRTCMediaEndpoint::fireTrackEvent(Ref<RTCRtpReceiver>&& receiver, Ref<MediaStreamTrack>&& track, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& rtcStreams, RefPtr<RTCRtpTransceiver>&& transceiver)
+{
</ins><span class="cx">     Vector<RefPtr<MediaStream>> streams;
</span><span class="cx">     for (auto& rtcStream : rtcStreams) {
</span><span class="cx">         auto& mediaStream = mediaStreamFromRTCStream(*rtcStream.get());
</span><span class="cx">         streams.append(&mediaStream);
</span><del>-        mediaStream.addTrackFromPlatform(*track);
</del><ins>+        mediaStream.addTrackFromPlatform(track.get());
</ins><span class="cx">     }
</span><span class="cx">     m_peerConnectionBackend.connection().fireEvent(RTCTrackEvent::create(eventNames().trackEvent,
</span><del>-        Event::CanBubble::No, Event::IsCancelable::No, WTFMove(receiver), track, WTFMove(streams), nullptr));
</del><ins>+        Event::CanBubble::No, Event::IsCancelable::No, WTFMove(receiver), WTFMove(track), WTFMove(streams), WTFMove(transceiver)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline void setExistingReceiverSourceTrack(RealtimeMediaSource& existingSource, webrtc::RtpReceiverInterface& rtcReceiver)
+{
+    switch (rtcReceiver.media_type()) {
+    case cricket::MEDIA_TYPE_AUDIO: {
+        ASSERT(existingSource.type() == RealtimeMediaSource::Type::Audio);
+        rtc::scoped_refptr<webrtc::AudioTrackInterface> audioTrack = static_cast<webrtc::AudioTrackInterface*>(rtcReceiver.track().get());
+        static_cast<RealtimeIncomingAudioSource&>(existingSource).setSourceTrack(WTFMove(audioTrack));
+        return;
+    }
+    case cricket::MEDIA_TYPE_VIDEO: {
+        ASSERT(existingSource.type() == RealtimeMediaSource::Type::Video);
+        rtc::scoped_refptr<webrtc::VideoTrackInterface> videoTrack = static_cast<webrtc::VideoTrackInterface*>(rtcReceiver.track().get());
+        static_cast<RealtimeIncomingVideoSource&>(existingSource).setSourceTrack(WTFMove(videoTrack));
+        return;
+    }
+    case cricket::MEDIA_TYPE_DATA:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+}
+
+static inline RefPtr<RealtimeMediaSource> sourceFromNewReceiver(webrtc::RtpReceiverInterface& rtcReceiver)
+{
+    auto rtcTrack = rtcReceiver.track();
+    switch (rtcReceiver.media_type()) {
+    case cricket::MEDIA_TYPE_DATA:
+        return nullptr;
+    case cricket::MEDIA_TYPE_AUDIO: {
+        rtc::scoped_refptr<webrtc::AudioTrackInterface> audioTrack = static_cast<webrtc::AudioTrackInterface*>(rtcTrack.get());
+        return RealtimeIncomingAudioSource::create(WTFMove(audioTrack), fromStdString(rtcTrack->id()));
+    }
+    case cricket::MEDIA_TYPE_VIDEO: {
+        rtc::scoped_refptr<webrtc::VideoTrackInterface> videoTrack = static_cast<webrtc::VideoTrackInterface*>(rtcTrack.get());
+        return RealtimeIncomingVideoSource::create(WTFMove(videoTrack), fromStdString(rtcTrack->id()));
+    }
+    }
+}
+
+void LibWebRTCMediaEndpoint::newTransceiver(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>&& rtcTransceiver)
+{
+    auto* transceiver = m_peerConnectionBackend.existingTransceiver([&](auto& transceiverBackend) {
+        return rtcTransceiver.get() == transceiverBackend.rtcTransceiver();
+    });
+    if (transceiver) {
+        setExistingReceiverSourceTrack(transceiver->receiver().track()->source(), *rtcTransceiver->receiver());
+        return;
+    }
+
+    auto rtcReceiver = rtcTransceiver->receiver();
+    auto source = sourceFromNewReceiver(*rtcReceiver);
+    if (!source)
+        return;
+
+    auto& newTransceiver = m_peerConnectionBackend.newRemoteTransceiver(std::make_unique<LibWebRTCRtpTransceiverBackend>(WTFMove(rtcTransceiver)), source.releaseNonNull());
+
+    fireTrackEvent(makeRef(newTransceiver.receiver()), *newTransceiver.receiver().track(), rtcReceiver->streams(), makeRef(newTransceiver));
+}
+
+template<typename T>
+std::optional<LibWebRTCMediaEndpoint::Backends> LibWebRTCMediaEndpoint::createTransceiverBackends(T&& trackOrKind, const RTCRtpTransceiverInit& init, LibWebRTCRtpSenderBackend::Source&& source)
+{
+    auto result = m_backend->AddTransceiver(WTFMove(trackOrKind), fromRtpTransceiverInit(init));
+    if (!result.ok())
+        return std::nullopt;
+
+    auto transceiver = std::make_unique<LibWebRTCRtpTransceiverBackend>(result.MoveValue());
+    return LibWebRTCMediaEndpoint::Backends { transceiver->createSenderBackend(m_peerConnectionBackend, WTFMove(source)), transceiver->createReceiverBackend(), WTFMove(transceiver) };
+}
+
+std::optional<LibWebRTCMediaEndpoint::Backends> LibWebRTCMediaEndpoint::addTransceiver(const String& trackKind, const RTCRtpTransceiverInit& init)
+{
+    auto type = trackKind == "audio" ? cricket::MediaType::MEDIA_TYPE_AUDIO : cricket::MediaType::MEDIA_TYPE_VIDEO;
+    return createTransceiverBackends(type, init, nullptr);
+}
+
+std::optional<LibWebRTCMediaEndpoint::Backends> LibWebRTCMediaEndpoint::addTransceiver(MediaStreamTrack& track, const RTCRtpTransceiverInit& init)
+{
+    LibWebRTCRtpSenderBackend::Source source;
+    rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> rtcTrack;
+    switch (track.privateTrack().type()) {
+    case RealtimeMediaSource::Type::None:
+        return std::nullopt;
+    case RealtimeMediaSource::Type::Audio: {
+        auto audioSource = RealtimeOutgoingAudioSource::create(track.privateTrack());
+        rtcTrack = m_peerConnectionFactory.CreateAudioTrack(track.id().utf8().data(), audioSource.ptr());
+        source = WTFMove(audioSource);
+        break;
+    }
+    case RealtimeMediaSource::Type::Video: {
+        auto videoSource = RealtimeOutgoingVideoSource::create(track.privateTrack());
+        rtcTrack = m_peerConnectionFactory.CreateVideoTrack(track.id().utf8().data(), videoSource.ptr());
+        source = WTFMove(videoSource);
+        break;
+    }
+    }
+
+    return createTransceiverBackends(WTFMove(rtcTrack), init, WTFMove(source));
+}
+
+std::unique_ptr<LibWebRTCRtpTransceiverBackend> LibWebRTCMediaEndpoint::transceiverBackendFromSender(LibWebRTCRtpSenderBackend& backend)
+{
+    for (auto& transceiver : m_backend->GetTransceivers()) {
+        if (transceiver->sender().get() == backend.rtcSender())
+            return std::make_unique<LibWebRTCRtpTransceiverBackend>(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>(transceiver));
+    }
+    return nullptr;
+}
+
+
</ins><span class="cx"> void LibWebRTCMediaEndpoint::removeRemoteStream(webrtc::MediaStreamInterface& rtcStream)
</span><span class="cx"> {
</span><span class="cx">     bool removed = m_streams.remove(&rtcStream);
</span><span class="lines">@@ -403,6 +520,9 @@
</span><span class="cx"> 
</span><span class="cx"> void LibWebRTCMediaEndpoint::OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& streams)
</span><span class="cx"> {
</span><ins>+    if (RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled())
+        return;
+
</ins><span class="cx">     callOnMainThread([protectedThis = makeRef(*this), receiver = WTFMove(receiver), streams]() mutable {
</span><span class="cx">         if (protectedThis->isStopped())
</span><span class="cx">             return;
</span><span class="lines">@@ -410,6 +530,19 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void LibWebRTCMediaEndpoint::OnTrack(rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver)
+{
+    if (!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled())
+        return;
+
+    callOnMainThread([protectedThis = makeRef(*this), transceiver = WTFMove(transceiver)]() mutable {
+        if (protectedThis->isStopped())
+            return;
+        protectedThis->newTransceiver(WTFMove(transceiver));
+    });
+}
+
+
</ins><span class="cx"> std::unique_ptr<RTCDataChannelHandler> LibWebRTCMediaEndpoint::createDataChannel(const String& label, const RTCDataChannelInit& options)
</span><span class="cx"> {
</span><span class="cx">     auto init = LibWebRTCDataChannelHandler::fromRTCDataChannelInit(options);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -28,10 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #include "LibWebRTCObservers.h"
</span><span class="cx"> #include "LibWebRTCProvider.h"
</span><del>-#include "PeerConnectionBackend.h"
</del><ins>+#include "LibWebRTCRtpSenderBackend.h"
</ins><span class="cx"> #include "RTCRtpReceiver.h"
</span><del>-#include "RealtimeOutgoingAudioSource.h"
-#include "RealtimeOutgoingVideoSource.h"
</del><span class="cx"> #include <Timer.h>
</span><span class="cx"> 
</span><span class="cx"> #pragma GCC diagnostic push
</span><span class="lines">@@ -61,7 +59,8 @@
</span><span class="cx"> 
</span><span class="cx"> class LibWebRTCProvider;
</span><span class="cx"> class LibWebRTCPeerConnectionBackend;
</span><del>-class LibWebRTCRtpSenderBackend;
</del><ins>+class LibWebRTCRtpReceiverBackend;
+class LibWebRTCRtpTransceiverBackend;
</ins><span class="cx"> class MediaStreamTrack;
</span><span class="cx"> class RTCSessionDescription;
</span><span class="cx"> 
</span><span class="lines">@@ -101,6 +100,15 @@
</span><span class="cx">     bool addTrack(LibWebRTCRtpSenderBackend&, MediaStreamTrack&, const Vector<String>&);
</span><span class="cx">     void removeTrack(LibWebRTCRtpSenderBackend&);
</span><span class="cx"> 
</span><ins>+    struct Backends {
+        std::unique_ptr<LibWebRTCRtpSenderBackend> senderBackend;
+        std::unique_ptr<LibWebRTCRtpReceiverBackend> receiverBackend;
+        std::unique_ptr<LibWebRTCRtpTransceiverBackend> transceiverBackend;
+    };
+    std::optional<Backends> addTransceiver(const String& trackKind, const RTCRtpTransceiverInit&);
+    std::optional<Backends> addTransceiver(MediaStreamTrack&, const RTCRtpTransceiverInit&);
+    std::unique_ptr<LibWebRTCRtpTransceiverBackend> transceiverBackendFromSender(LibWebRTCRtpSenderBackend&);
+
</ins><span class="cx"> private:
</span><span class="cx">     LibWebRTCMediaEndpoint(LibWebRTCPeerConnectionBackend&, LibWebRTCProvider&);
</span><span class="cx"> 
</span><span class="lines">@@ -110,6 +118,8 @@
</span><span class="cx">     void OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final;
</span><span class="cx">     void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>) final;
</span><span class="cx">     void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&) final;
</span><ins>+    void OnTrack(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>) final;
+
</ins><span class="cx">     void OnRenegotiationNeeded() final;
</span><span class="cx">     void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState) final;
</span><span class="cx">     void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState) final;
</span><span class="lines">@@ -125,7 +135,13 @@
</span><span class="cx">     void addRemoteStream(webrtc::MediaStreamInterface&);
</span><span class="cx">     void addRemoteTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>&&, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&);
</span><span class="cx">     void removeRemoteStream(webrtc::MediaStreamInterface&);
</span><ins>+    void newTransceiver(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>&&);
</ins><span class="cx"> 
</span><ins>+    void fireTrackEvent(Ref<RTCRtpReceiver>&&, Ref<MediaStreamTrack>&&, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&, RefPtr<RTCRtpTransceiver>&&);
+
+    template<typename T>
+    std::optional<Backends> createTransceiverBackends(T&&, const RTCRtpTransceiverInit&, LibWebRTCRtpSenderBackend::Source&&);
+
</ins><span class="cx">     void OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>&) final;
</span><span class="cx">     void gatherStatsForLogging();
</span><span class="cx">     void startLoggingStats();
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp    2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp       2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include "LibWebRTCMediaEndpoint.h"
</span><span class="cx"> #include "LibWebRTCRtpReceiverBackend.h"
</span><span class="cx"> #include "LibWebRTCRtpSenderBackend.h"
</span><ins>+#include "LibWebRTCRtpTransceiverBackend.h"
</ins><span class="cx"> #include "MediaEndpointConfiguration.h"
</span><span class="cx"> #include "Page.h"
</span><span class="cx"> #include "RTCIceCandidate.h"
</span><span class="lines">@@ -200,12 +201,12 @@
</span><span class="cx">     addIceCandidateSucceeded();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline Ref<RTCRtpReceiver> createReceiverForSource(ScriptExecutionContext& context, Ref<RealtimeMediaSource>&& source)
</del><ins>+static inline Ref<RTCRtpReceiver> createReceiverForSource(ScriptExecutionContext& context, Ref<RealtimeMediaSource>&& source, std::unique_ptr<RTCRtpReceiverBackend>&& backend)
</ins><span class="cx"> {
</span><span class="cx">     auto remoteTrackPrivate = MediaStreamTrackPrivate::create(WTFMove(source), String { source->id() });
</span><span class="cx">     auto remoteTrack = MediaStreamTrack::create(context, WTFMove(remoteTrackPrivate));
</span><span class="cx"> 
</span><del>-    return RTCRtpReceiver::create(WTFMove(remoteTrack));
</del><ins>+    return RTCRtpReceiver::create(WTFMove(remoteTrack), WTFMove(backend));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline Ref<RealtimeMediaSource> createEmptySource(const String& trackKind, String&& trackId)
</span><span class="lines">@@ -219,7 +220,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref<RTCRtpReceiver> LibWebRTCPeerConnectionBackend::createReceiver(const String& trackKind, const String& trackId)
</span><span class="cx"> {
</span><del>-    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), createEmptySource(trackKind, String(trackId)));
</del><ins>+    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), createEmptySource(trackKind, String(trackId)), nullptr);
</ins><span class="cx">     m_pendingReceivers.append(receiver.copyRef());
</span><span class="cx">     return receiver;
</span><span class="cx"> }
</span><span class="lines">@@ -237,7 +238,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     auto source = RealtimeIncomingVideoSource::create(nullptr, WTFMove(trackId));
</span><del>-    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), source.copyRef());
</del><ins>+    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), source.copyRef(), nullptr);
</ins><span class="cx"> 
</span><span class="cx">     auto senderBackend = std::make_unique<LibWebRTCRtpSenderBackend>(*this, nullptr);
</span><span class="cx">     auto transceiver = RTCRtpTransceiver::create(RTCRtpSender::create("video", { }, WTFMove(senderBackend)), receiver.copyRef(), nullptr);
</span><span class="lines">@@ -260,7 +261,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     auto source = RealtimeIncomingAudioSource::create(nullptr, WTFMove(trackId));
</span><del>-    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), source.copyRef());
</del><ins>+    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), source.copyRef(), nullptr);
</ins><span class="cx"> 
</span><span class="cx">     auto senderBackend = std::make_unique<LibWebRTCRtpSenderBackend>(*this, nullptr);
</span><span class="cx">     auto transceiver = RTCRtpTransceiver::create(RTCRtpSender::create("audio", { }, WTFMove(senderBackend)), receiver.copyRef(), nullptr);
</span><span class="lines">@@ -316,11 +317,57 @@
</span><span class="cx"> 
</span><span class="cx"> static inline LibWebRTCRtpSenderBackend& backendFromRTPSender(RTCRtpSender& sender)
</span><span class="cx"> {
</span><ins>+    ASSERT(!sender.isStopped());
</ins><span class="cx">     return static_cast<LibWebRTCRtpSenderBackend&>(*sender.backend());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ExceptionOr<Ref<RTCRtpSender>> LibWebRTCPeerConnectionBackend::addTrack(RTCRtpSender* sender, MediaStreamTrack& track, const Vector<String>& mediaStreamIds)
</del><ins>+
+static inline RefPtr<RTCRtpSender> findExistingSender(const Vector<std::reference_wrapper<RTCRtpSender>>& senders, LibWebRTCRtpSenderBackend& senderBackend)
</ins><span class="cx"> {
</span><ins>+    ASSERT(senderBackend.rtcSender());
+    for (RTCRtpSender& sender : senders) {
+        if (!sender.isStopped() && senderBackend.rtcSender() == backendFromRTPSender(sender).rtcSender())
+            return makeRef(sender);
+    }
+    return nullptr;
+}
+
+ExceptionOr<Ref<RTCRtpSender>> LibWebRTCPeerConnectionBackend::addTrack(MediaStreamTrack& track, Vector<String>&& mediaStreamIds)
+{
+    if (RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled()) {
+        auto senderBackend = std::make_unique<LibWebRTCRtpSenderBackend>(*this, nullptr);
+        if (!m_endpoint->addTrack(*senderBackend, track, mediaStreamIds))
+            return Exception { TypeError, "Unable to add track"_s };
+
+        if (auto sender = findExistingSender(m_peerConnection.getSenders(), *senderBackend)) {
+            sender->setTrack(makeRef(track));
+            sender->setMediaStreamIds(WTFMove(mediaStreamIds));
+            return sender.releaseNonNull();
+        }
+
+        auto transceiverBackend = m_endpoint->transceiverBackendFromSender(*senderBackend);
+
+        auto sender = RTCRtpSender::create(makeRef(track), WTFMove(mediaStreamIds), WTFMove(senderBackend));
+        auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), createEmptySource(track.kind(), createCanonicalUUIDString()), transceiverBackend->createReceiverBackend());
+        auto transceiver = RTCRtpTransceiver::create(sender.copyRef(), WTFMove(receiver), WTFMove(transceiverBackend));
+        m_peerConnection.addInternalTransceiver(WTFMove(transceiver));
+        return WTFMove(sender);
+    }
+
+    RTCRtpSender* sender = nullptr;
+    // Reuse an existing sender with the same track kind if it has never been used to send before.
+    for (auto& transceiver : m_peerConnection.getTransceivers()) {
+        auto& existingSender = transceiver->sender();
+        if (!existingSender.isStopped() && existingSender.trackKind() == track.kind() && existingSender.trackId().isNull() && !transceiver->hasSendingDirection()) {
+            existingSender.setTrack(makeRef(track));
+            existingSender.setMediaStreamIds(WTFMove(mediaStreamIds));
+            transceiver->enableSendingDirection();
+            sender = &existingSender;
+
+            break;
+        }
+    }
+
</ins><span class="cx">     if (!sender) {
</span><span class="cx">         const String& trackKind = track.kind();
</span><span class="cx">         String trackId = createCanonicalUUIDString();
</span><span class="lines">@@ -340,8 +387,25 @@
</span><span class="cx">     return makeRef(*sender);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template<typename T>
+ExceptionOr<Ref<RTCRtpTransceiver>> LibWebRTCPeerConnectionBackend::addUnifiedPlanTransceiver(T&& trackOrKind, const RTCRtpTransceiverInit& init)
+{
+    auto backends = m_endpoint->addTransceiver(trackOrKind, init);
+    if (!backends)
+        return Exception { InvalidAccessError, "Unable to add transceiver"_s };
+
+    auto sender = RTCRtpSender::create(WTFMove(trackOrKind), Vector<String> { }, WTFMove(backends->senderBackend));
+    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), createEmptySource(sender->trackKind(), createCanonicalUUIDString()), WTFMove(backends->receiverBackend));
+    auto transceiver = RTCRtpTransceiver::create(WTFMove(sender), WTFMove(receiver), WTFMove(backends->transceiverBackend));
+    m_peerConnection.addInternalTransceiver(transceiver.copyRef());
+    return WTFMove(transceiver);
+}
+
</ins><span class="cx"> ExceptionOr<Ref<RTCRtpTransceiver>> LibWebRTCPeerConnectionBackend::addTransceiver(const String& trackKind, const RTCRtpTransceiverInit& init)
</span><span class="cx"> {
</span><ins>+    if (RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled())
+        return addUnifiedPlanTransceiver(String { trackKind }, init);
+
</ins><span class="cx">     auto senderBackend = std::make_unique<LibWebRTCRtpSenderBackend>(*this, nullptr);
</span><span class="cx">     auto newSender = RTCRtpSender::create(String(trackKind), Vector<String>(), WTFMove(senderBackend));
</span><span class="cx">     return completeAddTransceiver(WTFMove(newSender), init, createCanonicalUUIDString(), trackKind);
</span><span class="lines">@@ -349,6 +413,9 @@
</span><span class="cx"> 
</span><span class="cx"> ExceptionOr<Ref<RTCRtpTransceiver>> LibWebRTCPeerConnectionBackend::addTransceiver(Ref<MediaStreamTrack>&& track, const RTCRtpTransceiverInit& init)
</span><span class="cx"> {
</span><ins>+    if (RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled())
+        return addUnifiedPlanTransceiver(WTFMove(track), init);
+
</ins><span class="cx">     auto senderBackend = std::make_unique<LibWebRTCRtpSenderBackend>(*this, nullptr);
</span><span class="cx">     auto& backend = *senderBackend;
</span><span class="cx">     auto sender = RTCRtpSender::create(track.copyRef(), Vector<String>(), WTFMove(senderBackend));
</span><span class="lines">@@ -358,6 +425,29 @@
</span><span class="cx">     return completeAddTransceiver(WTFMove(sender), init, track->id(), track->kind());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline LibWebRTCRtpTransceiverBackend& backendFromRTPTransceiver(RTCRtpTransceiver& transceiver)
+{
+    return static_cast<LibWebRTCRtpTransceiverBackend&>(*transceiver.backend());
+}
+
+RTCRtpTransceiver* LibWebRTCPeerConnectionBackend::existingTransceiver(WTF::Function<bool(LibWebRTCRtpTransceiverBackend&)>&& matchingFunction)
+{
+    for (auto& transceiver : m_peerConnection.getTransceivers()) {
+        if (matchingFunction(backendFromRTPTransceiver(*transceiver)))
+            return transceiver.get();
+    }
+    return nullptr;
+}
+
+RTCRtpTransceiver& LibWebRTCPeerConnectionBackend::newRemoteTransceiver(std::unique_ptr<LibWebRTCRtpTransceiverBackend>&& transceiverBackend, Ref<RealtimeMediaSource>&& receiverSource)
+{
+    auto sender = RTCRtpSender::create(receiverSource->type() == RealtimeMediaSource::Type::Audio ? "audio"_s : "video"_s, Vector<String> { }, transceiverBackend->createSenderBackend(*this, nullptr));
+    auto receiver = createReceiverForSource(*m_peerConnection.scriptExecutionContext(), WTFMove(receiverSource), transceiverBackend->createReceiverBackend());
+    auto transceiver = RTCRtpTransceiver::create(WTFMove(sender), WTFMove(receiver), WTFMove(transceiverBackend));
+    m_peerConnection.addInternalTransceiver(transceiver.copyRef());
+    return transceiver.get();
+}
+
</ins><span class="cx"> Ref<RTCRtpTransceiver> LibWebRTCPeerConnectionBackend::completeAddTransceiver(Ref<RTCRtpSender>&& sender, const RTCRtpTransceiverInit& init, const String& trackId, const String& trackKind)
</span><span class="cx"> {
</span><span class="cx">     auto transceiver = RTCRtpTransceiver::create(WTFMove(sender), createReceiver(trackKind, trackId), nullptr);
</span><span class="lines">@@ -373,21 +463,13 @@
</span><span class="cx">     m_endpoint->removeTrack(backendFromRTPSender(sender));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template<typename Source>
-static inline bool updateTrackSource(Source& source, MediaStreamTrack* track)
-{
-    if (!track) {
-        source.stop();
-        return true;
-    }
-    return source.setSource(track->privateTrack());
-}
-
</del><span class="cx"> void LibWebRTCPeerConnectionBackend::applyRotationForOutgoingVideoSources()
</span><span class="cx"> {
</span><span class="cx">     for (auto& transceiver : m_peerConnection.getTransceivers()) {
</span><del>-        if (auto* videoSource = backendFromRTPSender(transceiver->sender()).videoSource())
-            videoSource->setApplyRotation(true);
</del><ins>+        if (!transceiver->sender().isStopped()) {
+            if (auto* videoSource = backendFromRTPSender(transceiver->sender()).videoSource())
+                videoSource->setApplyRotation(true);
+        }
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -38,11 +38,13 @@
</span><span class="cx"> 
</span><span class="cx"> class LibWebRTCMediaEndpoint;
</span><span class="cx"> class LibWebRTCProvider;
</span><ins>+class LibWebRTCRtpTransceiverBackend;
</ins><span class="cx"> class RTCRtpReceiver;
</span><span class="cx"> class RTCSessionDescription;
</span><span class="cx"> class RTCStatsReport;
</span><span class="cx"> class RealtimeIncomingAudioSource;
</span><span class="cx"> class RealtimeIncomingVideoSource;
</span><ins>+class RealtimeMediaSource;
</ins><span class="cx"> class RealtimeOutgoingAudioSource;
</span><span class="cx"> class RealtimeOutgoingVideoSource;
</span><span class="cx"> 
</span><span class="lines">@@ -84,12 +86,15 @@
</span><span class="cx"> 
</span><span class="cx">     void getStatsSucceeded(const DeferredPromise&, Ref<RTCStatsReport>&&);
</span><span class="cx"> 
</span><del>-    ExceptionOr<Ref<RTCRtpSender>> addTrack(RTCRtpSender*, MediaStreamTrack&, const Vector<String>&) final;
</del><ins>+    ExceptionOr<Ref<RTCRtpSender>> addTrack(MediaStreamTrack&, Vector<String>&&) final;
</ins><span class="cx">     void removeTrack(RTCRtpSender&) final;
</span><span class="cx"> 
</span><span class="cx">     ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(const String&, const RTCRtpTransceiverInit&) final;
</span><span class="cx">     ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(Ref<MediaStreamTrack>&&, const RTCRtpTransceiverInit&) final;
</span><span class="cx"> 
</span><ins>+    RTCRtpTransceiver* existingTransceiver(WTF::Function<bool(LibWebRTCRtpTransceiverBackend&)>&&);
+    RTCRtpTransceiver& newRemoteTransceiver(std::unique_ptr<LibWebRTCRtpTransceiverBackend>&&, Ref<RealtimeMediaSource>&&);
+
</ins><span class="cx">     struct VideoReceiver {
</span><span class="cx">         Ref<RTCRtpReceiver> receiver;
</span><span class="cx">         Ref<RealtimeIncomingVideoSource> source;
</span><span class="lines">@@ -108,6 +113,9 @@
</span><span class="cx"> 
</span><span class="cx">     Ref<RTCRtpReceiver> createReceiver(const String& trackKind, const String& trackId);
</span><span class="cx"> 
</span><ins>+    template<typename T>
+    ExceptionOr<Ref<RTCRtpTransceiver>> addUnifiedPlanTransceiver(T&& trackOrKind, const RTCRtpTransceiverInit&);
+
</ins><span class="cx">     Ref<LibWebRTCMediaEndpoint> m_endpoint;
</span><span class="cx">     bool m_isLocalDescriptionSet { false };
</span><span class="cx">     bool m_isRemoteDescriptionSet { false };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpSenderBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp 2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.cpp    2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -90,7 +90,7 @@
</span><span class="cx">         protectedSender->setTrack(track.releaseNonNull());
</span><span class="cx">         if (!hasTrack) {
</span><span class="cx">             // FIXME: In case of unified plan, we should use m_rtcSender->SetTrack and no longer need m_peerConnectionBackend.
</span><del>-            auto result = m_peerConnectionBackend->addTrack(protectedSender.ptr(), *protectedSender->track(), { });
</del><ins>+            auto result = m_peerConnectionBackend->addTrack(*protectedSender->track(), { });
</ins><span class="cx">             if (result.hasException()) {
</span><span class="cx">                 promise.reject(result.releaseException());
</span><span class="cx">                 return;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpSenderBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderBackend.h      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #if ENABLE(WEB_RTC)
</span><span class="cx"> 
</span><span class="cx"> #include "LibWebRTCMacros.h"
</span><ins>+#include "LibWebRTCPeerConnectionBackend.h"
</ins><span class="cx"> #include "RTCRtpSenderBackend.h"
</span><span class="cx"> #include "RealtimeOutgoingAudioSource.h"
</span><span class="cx"> #include "RealtimeOutgoingVideoSource.h"
</span><span class="lines">@@ -46,12 +47,20 @@
</span><span class="cx"> 
</span><span class="cx"> class LibWebRTCRtpSenderBackend final : public RTCRtpSenderBackend {
</span><span class="cx"> public:
</span><del>-    explicit LibWebRTCRtpSenderBackend(LibWebRTCPeerConnectionBackend& backend, rtc::scoped_refptr<webrtc::RtpSenderInterface>&& rtcSender)
</del><ins>+    LibWebRTCRtpSenderBackend(LibWebRTCPeerConnectionBackend& backend, rtc::scoped_refptr<webrtc::RtpSenderInterface>&& rtcSender)
</ins><span class="cx">         : m_peerConnectionBackend(makeWeakPtr(&backend))
</span><span class="cx">         , m_rtcSender(WTFMove(rtcSender))
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    using Source = Variant<std::nullptr_t, Ref<RealtimeOutgoingAudioSource>, Ref<RealtimeOutgoingVideoSource>>;
+    LibWebRTCRtpSenderBackend(LibWebRTCPeerConnectionBackend& backend, rtc::scoped_refptr<webrtc::RtpSenderInterface>&& rtcSender, Source&& source)
+        : m_peerConnectionBackend(makeWeakPtr(&backend))
+        , m_rtcSender(WTFMove(rtcSender))
+        , m_source(WTFMove(source))
+    {
+    }
+
</ins><span class="cx">     void setRTCSender(rtc::scoped_refptr<webrtc::RtpSenderInterface>&& rtcSender) { m_rtcSender = WTFMove(rtcSender); }
</span><span class="cx">     webrtc::RtpSenderInterface* rtcSender() { return m_rtcSender.get(); }
</span><span class="cx"> 
</span><span class="lines">@@ -71,26 +80,21 @@
</span><span class="cx">         );
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool hasNoSource() const
</del><ins>+    bool hasSource() const
</ins><span class="cx">     {
</span><span class="cx">         return WTF::switchOn(m_source,
</span><del>-            [] (const std::nullptr_t&) { return true; },
-            [] (const auto&) { return false; }
</del><ins>+            [] (const std::nullptr_t&) { return false; },
+            [] (const auto&) { return true; }
</ins><span class="cx">         );
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void setSource(Ref<RealtimeOutgoingAudioSource>&& source)
</del><ins>+    void setSource(Source&& source)
</ins><span class="cx">     {
</span><del>-        ASSERT(hasNoSource());
</del><ins>+        ASSERT(!hasSource());
</ins><span class="cx">         m_source = WTFMove(source);
</span><ins>+        ASSERT(hasSource());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void setSource(Ref<RealtimeOutgoingVideoSource>&& source)
-    {
-        ASSERT(hasNoSource());
-        m_source = WTFMove(source);
-    }
-
</del><span class="cx"> private:
</span><span class="cx">     void replaceTrack(ScriptExecutionContext&, RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromiseDeferred<void>&&) final;
</span><span class="cx">     RTCRtpParameters getParameters() const final;
</span><span class="lines">@@ -98,7 +102,7 @@
</span><span class="cx"> 
</span><span class="cx">     WeakPtr<LibWebRTCPeerConnectionBackend> m_peerConnectionBackend;
</span><span class="cx">     rtc::scoped_refptr<webrtc::RtpSenderInterface> m_rtcSender;
</span><del>-    Variant<std::nullptr_t, Ref<RealtimeOutgoingAudioSource>, Ref<RealtimeOutgoingVideoSource>> m_source;
</del><ins>+    Source m_source;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpTransceiverBackendcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp (0 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp                            (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.cpp       2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) 2018 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCRtpTransceiverBackend.h"
+
+#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
+
+#include "LibWebRTCRtpReceiverBackend.h"
+#include "LibWebRTCRtpSenderBackend.h"
+#include "LibWebRTCUtils.h"
+
+namespace WebCore {
+
+std::unique_ptr<LibWebRTCRtpReceiverBackend> LibWebRTCRtpTransceiverBackend::createReceiverBackend()
+{
+    return std::make_unique<LibWebRTCRtpReceiverBackend>(m_rtcTransceiver->receiver());
+}
+
+std::unique_ptr<LibWebRTCRtpSenderBackend> LibWebRTCRtpTransceiverBackend::createSenderBackend(LibWebRTCPeerConnectionBackend& backend, LibWebRTCRtpSenderBackend::Source&& source)
+{
+    return std::make_unique<LibWebRTCRtpSenderBackend>(backend, m_rtcTransceiver->sender(), WTFMove(source));
+}
+
+RTCRtpTransceiverDirection LibWebRTCRtpTransceiverBackend::direction() const
+{
+    return toRTCRtpTransceiverDirection(m_rtcTransceiver->direction());
+}
+
+std::optional<RTCRtpTransceiverDirection> LibWebRTCRtpTransceiverBackend::currentDirection() const
+{
+    auto value = m_rtcTransceiver->current_direction();
+    if (!value)
+        return std::nullopt;
+    return toRTCRtpTransceiverDirection(*value);
+}
+
+void LibWebRTCRtpTransceiverBackend::setDirection(RTCRtpTransceiverDirection direction)
+{
+    m_rtcTransceiver->SetDirection(fromRTCRtpTransceiverDirection(direction));
+}
+
+String LibWebRTCRtpTransceiverBackend::mid()
+{
+    if (auto mid = m_rtcTransceiver->mid())
+        return fromStdString(*mid);
+    return String { };
+}
+
+void LibWebRTCRtpTransceiverBackend::stop()
+{
+    m_rtcTransceiver->Stop();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC) && USE(LIBWEBRTC)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCRtpTransceiverBackendhfromrev235808trunkSourceWebCoreModulesmediastreamRTCRtpTransceiverBackendh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.h (from rev 235808, trunk/Source/WebCore/Modules/mediastream/RTCRtpTransceiverBackend.h) (0 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.h                              (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransceiverBackend.h 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * Copyright (C) 2018 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
+
+#include "LibWebRTCMacros.h"
+#include "LibWebRTCRtpSenderBackend.h"
+#include "RTCRtpTransceiverBackend.h"
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+#include <webrtc/api/rtptransceiverinterface.h>
+#include <webrtc/rtc_base/scoped_ref_ptr.h>
+
+#pragma GCC diagnostic pop
+
+namespace WebCore {
+
+class LibWebRTCRtpReceiverBackend;
+
+class LibWebRTCRtpTransceiverBackend final : public RTCRtpTransceiverBackend {
+public:
+    explicit LibWebRTCRtpTransceiverBackend(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>&& rtcTransceiver)
+        : m_rtcTransceiver(WTFMove(rtcTransceiver))
+    {
+    }
+
+    std::unique_ptr<LibWebRTCRtpReceiverBackend> createReceiverBackend();
+    std::unique_ptr<LibWebRTCRtpSenderBackend> createSenderBackend(LibWebRTCPeerConnectionBackend&, LibWebRTCRtpSenderBackend::Source&&);
+
+    webrtc::RtpTransceiverInterface* rtcTransceiver() { return m_rtcTransceiver.get(); }
+
+private:
+    RTCRtpTransceiverDirection direction() const final;
+    std::optional<RTCRtpTransceiverDirection> currentDirection() const final;
+    void setDirection(RTCRtpTransceiverDirection) final;
+    String mid() final;
+    void stop() final;
+
+    rtc::scoped_refptr<webrtc::RtpTransceiverInterface> m_rtcTransceiver;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC) && USE(LIBWEBRTC)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCUtilscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp    2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.cpp       2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -28,10 +28,18 @@
</span><span class="cx"> #if USE(LIBWEBRTC)
</span><span class="cx"> 
</span><span class="cx"> #include "LibWebRTCMacros.h"
</span><ins>+#include "RTCPeerConnection.h"
</ins><span class="cx"> #include "RTCRtpParameters.h"
</span><del>-#include <webrtc/api/rtpparameters.h>
</del><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx"> 
</span><ins>+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+#include <webrtc/api/rtpparameters.h>
+#include <webrtc/api/rtptransceiverinterface.h>
+
+#pragma GCC diagnostic pop
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> static inline RTCRtpParameters::EncodingParameters toRTCEncodingParameters(const webrtc::RtpEncodingParameters& rtcParameters)
</span><span class="lines">@@ -177,6 +185,41 @@
</span><span class="cx">     return rtcParameters;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RTCRtpTransceiverDirection toRTCRtpTransceiverDirection(webrtc::RtpTransceiverDirection rtcDirection)
+{
+    switch (rtcDirection) {
+    case webrtc::RtpTransceiverDirection::kSendRecv:
+        return RTCRtpTransceiverDirection::Sendrecv;
+    case webrtc::RtpTransceiverDirection::kSendOnly:
+        return RTCRtpTransceiverDirection::Sendonly;
+    case webrtc::RtpTransceiverDirection::kRecvOnly:
+        return RTCRtpTransceiverDirection::Recvonly;
+    case webrtc::RtpTransceiverDirection::kInactive:
+        return RTCRtpTransceiverDirection::Inactive;
+    };
+}
+
+webrtc::RtpTransceiverDirection fromRTCRtpTransceiverDirection(RTCRtpTransceiverDirection direction)
+{
+    switch (direction) {
+    case RTCRtpTransceiverDirection::Sendrecv:
+        return webrtc::RtpTransceiverDirection::kSendRecv;
+    case RTCRtpTransceiverDirection::Sendonly:
+        return webrtc::RtpTransceiverDirection::kSendOnly;
+    case RTCRtpTransceiverDirection::Recvonly:
+        return webrtc::RtpTransceiverDirection::kRecvOnly;
+    case RTCRtpTransceiverDirection::Inactive:
+        return webrtc::RtpTransceiverDirection::kInactive;
+    };
+}
+
+webrtc::RtpTransceiverInit fromRtpTransceiverInit(const RTCRtpTransceiverInit& init)
+{
+    webrtc::RtpTransceiverInit rtcInit;
+    rtcInit.direction = fromRTCRtpTransceiverDirection(init.direction);
+    return rtcInit;
+}
+
</ins><span class="cx"> }; // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // USE(LIBWEBRTC)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCUtilsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.h      2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCUtils.h 2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -30,15 +30,25 @@
</span><span class="cx"> 
</span><span class="cx"> namespace webrtc {
</span><span class="cx"> struct RtpParameters;
</span><ins>+struct RtpTransceiverInit;
+
+enum class RtpTransceiverDirection;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> struct RTCRtpParameters;
</span><ins>+struct RTCRtpTransceiverInit;
</ins><span class="cx"> 
</span><ins>+enum class RTCRtpTransceiverDirection;
+
</ins><span class="cx"> RTCRtpParameters toRTCRtpParameters(const webrtc::RtpParameters&);
</span><span class="cx"> webrtc::RtpParameters fromRTCRtpParameters(const RTCRtpParameters&);
</span><span class="cx"> 
</span><ins>+RTCRtpTransceiverDirection toRTCRtpTransceiverDirection(webrtc::RtpTransceiverDirection);
+webrtc::RtpTransceiverDirection fromRTCRtpTransceiverDirection(RTCRtpTransceiverDirection);
+webrtc::RtpTransceiverInit fromRtpTransceiverInit(const RTCRtpTransceiverInit&);
+
</ins><span class="cx"> inline String fromStdString(const std::string& value)
</span><span class="cx"> {
</span><span class="cx">     return String::fromUTF8(value.data(), value.length());
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1103,6 +1103,7 @@
</span><span class="cx">          4186BD3E213EE3400001826F /* LibWebRTCUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1A049213EDDFD0063FB6B /* LibWebRTCUtils.cpp */; };
</span><span class="cx">          4186BD3F213EE3430001826F /* LibWebRTCRtpSenderBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1A04B213EDDFE0063FB6B /* LibWebRTCRtpSenderBackend.cpp */; };
</span><span class="cx">          4186BD40213EE3450001826F /* LibWebRTCRtpReceiverBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1A04A213EDDFE0063FB6B /* LibWebRTCRtpReceiverBackend.cpp */; };
</span><ins>+               4186BD4E2140B9E80001826F /* LibWebRTCRtpTransceiverBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4186BD4D2140B9E80001826F /* LibWebRTCRtpTransceiverBackend.cpp */; };
</ins><span class="cx">           41885B9311B6FDA6003383BB /* FormSubmission.h in Headers */ = {isa = PBXBuildFile; fileRef = 41885B9111B6FDA6003383BB /* FormSubmission.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          418A06D0133C04D500CD379C /* EventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 418A06CE133C04D500CD379C /* EventDispatcher.h */; };
</span><span class="cx">          418F88050FF957AF0080F045 /* JSAbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 418F88030FF957AE0080F045 /* JSAbstractWorker.h */; };
</span><span class="lines">@@ -7288,6 +7289,8 @@
</span><span class="cx">          4186BD3B213EDE380001826F /* LibWebRTCRtpReceiverBackend.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LibWebRTCRtpReceiverBackend.h; path = libwebrtc/LibWebRTCRtpReceiverBackend.h; sourceTree = "<group>"; };
</span><span class="cx">          4186BD3D213EDE390001826F /* LibWebRTCRtpSenderBackend.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LibWebRTCRtpSenderBackend.h; path = libwebrtc/LibWebRTCRtpSenderBackend.h; sourceTree = "<group>"; };
</span><span class="cx">          4186BD46214072B60001826F /* RTCRtpTransceiverBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCRtpTransceiverBackend.h; sourceTree = "<group>"; };
</span><ins>+               4186BD4B2140A8050001826F /* LibWebRTCRtpTransceiverBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCRtpTransceiverBackend.h; path = libwebrtc/LibWebRTCRtpTransceiverBackend.h; sourceTree = "<group>"; };
+               4186BD4D2140B9E80001826F /* LibWebRTCRtpTransceiverBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCRtpTransceiverBackend.cpp; path = libwebrtc/LibWebRTCRtpTransceiverBackend.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           41885B9111B6FDA6003383BB /* FormSubmission.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormSubmission.h; sourceTree = "<group>"; };
</span><span class="cx">          41885B9211B6FDA6003383BB /* FormSubmission.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormSubmission.cpp; sourceTree = "<group>"; };
</span><span class="cx">          418A06CE133C04D500CD379C /* EventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDispatcher.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -16894,6 +16897,8 @@
</span><span class="cx">                          4186BD3B213EDE380001826F /* LibWebRTCRtpReceiverBackend.h */,
</span><span class="cx">                          41D1A04B213EDDFE0063FB6B /* LibWebRTCRtpSenderBackend.cpp */,
</span><span class="cx">                          4186BD3D213EDE390001826F /* LibWebRTCRtpSenderBackend.h */,
</span><ins>+                               4186BD4D2140B9E80001826F /* LibWebRTCRtpTransceiverBackend.cpp */,
+                               4186BD4B2140A8050001826F /* LibWebRTCRtpTransceiverBackend.h */,
</ins><span class="cx">                           41D28D0B2139E01D00F4206F /* LibWebRTCStatsCollector.cpp */,
</span><span class="cx">                          41D28D0C2139E01E00F4206F /* LibWebRTCStatsCollector.h */,
</span><span class="cx">                          41D1A049213EDDFD0063FB6B /* LibWebRTCUtils.cpp */,
</span><span class="lines">@@ -28781,7 +28786,6 @@
</span><span class="cx">                          D6489D26166FFCF1007C031B /* JSHTMLTemplateElement.h in Headers */,
</span><span class="cx">                          A80E7E9D0A1A83E3007FB8C5 /* JSHTMLTextAreaElement.h in Headers */,
</span><span class="cx">                          83E359A21BB1031D002CEB98 /* JSHTMLTimeElement.h in Headers */,
</span><del>-                               E42050172141901B0066EF3B /* ProcessWarming.h in Headers */,
</del><span class="cx">                           A80E7B0C0A19D606007FB8C5 /* JSHTMLTitleElement.h in Headers */,
</span><span class="cx">                          070756D414239A4F00414161 /* JSHTMLTrackElement.h in Headers */,
</span><span class="cx">                          1A85B2110A1B258700D8C87C /* JSHTMLUListElement.h in Headers */,
</span><span class="lines">@@ -29789,6 +29793,7 @@
</span><span class="cx">                          B71FE6DF11091CB300DAEF77 /* PrintContext.h in Headers */,
</span><span class="cx">                          51F645D51FECDBCE00B54DED /* Process.h in Headers */,
</span><span class="cx">                          A8EA7EBC0A1945D000A8EF5F /* ProcessingInstruction.h in Headers */,
</span><ins>+                               E42050172141901B0066EF3B /* ProcessWarming.h in Headers */,
</ins><span class="cx">                           E44613EC0CD681B500FADA75 /* ProgressEvent.h in Headers */,
</span><span class="cx">                          A715E653134BBBEC00D8E713 /* ProgressShadowElement.h in Headers */,
</span><span class="cx">                          1A2A68240B5BEDE70002A480 /* ProgressTracker.h in Headers */,
</span><span class="lines">@@ -31525,6 +31530,7 @@
</span><span class="cx">                          417612B11E3A994000C3D81D /* LibWebRTCPeerConnectionBackend.cpp in Sources */,
</span><span class="cx">                          4186BD40213EE3450001826F /* LibWebRTCRtpReceiverBackend.cpp in Sources */,
</span><span class="cx">                          4186BD3F213EE3430001826F /* LibWebRTCRtpSenderBackend.cpp in Sources */,
</span><ins>+                               4186BD4E2140B9E80001826F /* LibWebRTCRtpTransceiverBackend.cpp in Sources */,
</ins><span class="cx">                           41D28D0D2139E05800F4206F /* LibWebRTCStatsCollector.cpp in Sources */,
</span><span class="cx">                          4186BD3E213EE3400001826F /* LibWebRTCUtils.cpp in Sources */,
</span><span class="cx">                          9759E93E14EF1CF80026A2DD /* LoadableTextTrack.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeIncomingAudioSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx">     : RealtimeMediaSource(WTFMove(audioTrackId), RealtimeMediaSource::Type::Audio, String())
</span><span class="cx">     , m_audioTrack(WTFMove(audioTrack))
</span><span class="cx"> {
</span><ins>+    setName("remote audio");
</ins><span class="cx">     notifyMutedChange(!m_audioTrack);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeIncomingVideoSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp        2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp   2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx">     : RealtimeMediaSource(WTFMove(videoTrackId), RealtimeMediaSource::Type::Video, String())
</span><span class="cx">     , m_videoTrack(WTFMove(videoTrack))
</span><span class="cx"> {
</span><ins>+    setName("remote video");
</ins><span class="cx">     m_currentSettings.setWidth(640);
</span><span class="cx">     m_currentSettings.setHeight(480);
</span><span class="cx">     notifyMutedChange(!m_videoTrack);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h  2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h     2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx">     virtual void setInterrupted(bool, bool);
</span><span class="cx"> 
</span><span class="cx">     const String& name() const { return m_name; }
</span><del>-    void setName(const String& name) { m_name = name; }
</del><ins>+    void setName(String&& name) { m_name = WTFMove(name); }
</ins><span class="cx"> 
</span><span class="cx">     unsigned fitnessScore() const { return m_fitnessScore; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (235808 => 235809)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp       2018-09-07 21:43:35 UTC (rev 235808)
+++ trunk/Source/WebCore/testing/Internals.cpp  2018-09-07 21:57:47 UTC (rev 235809)
</span><span class="lines">@@ -1386,6 +1386,9 @@
</span><span class="cx"> 
</span><span class="cx"> void Internals::useMockRTCPeerConnectionFactory(const String& testCase)
</span><span class="cx"> {
</span><ins>+    // FIXME: We should upgrade mocks to support unified plan APIs, until then use plan B in tests using mock.
+
+    ASSERT(!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled());
</ins><span class="cx">     if (!LibWebRTCProvider::webRTCAvailable())
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>