<!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>[282217] 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/282217">282217</a></dd>
<dt>Author</dt> <dd>youenn@apple.com</dd>
<dt>Date</dt> <dd>2021-09-09 09:08:51 -0700 (Thu, 09 Sep 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update RTCPeerConnection descriptions as per specification
https://bugs.webkit.org/show_bug.cgi?id=229963

Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

* web-platform-tests/webrtc/RTCPeerConnection-description-attributes-timing.https-expected.txt:
* web-platform-tests/webrtc/RTCPeerConnection-setLocalDescription-rollback-expected.txt:

Source/WebCore:

A peer connection has two sets of descriptions: main thread descriptions which are exposed to JS and signaling thread descriptions
which are used/modified internally by the backend.
WebRTC spec describes when signaling thread descriptions should be used to set main thread descriptions.
This should be done at the end of setting remote/local descriptions, as well as when adding or surfacing an ICE candidate.
We make sure to grab signaling thread descriptions at those moments, then hop to main thread to set the main thread descriptions.

In case of closed connection, we stop early as we do not need to surface new descriptions (as well as resolve promises/fire events).

Covered by rebased tests.

* Modules/mediastream/PeerConnectionBackend.cpp:
(WebCore::PeerConnectionBackend::setLocalDescriptionSucceeded):
(WebCore::PeerConnectionBackend::setRemoteDescriptionSucceeded):
(WebCore::PeerConnectionBackend::addIceCandidate):
(WebCore::PeerConnectionBackend::newICECandidate):
* Modules/mediastream/PeerConnectionBackend.h:
* Modules/mediastream/RTCPeerConnection.cpp:
(WebCore::updateDescription):
(WebCore::RTCPeerConnection::updateDescriptions):
* Modules/mediastream/RTCPeerConnection.h:
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::fromSessionDescriptionType):
(WebCore::descriptionsFromPeerConnection):
(WebCore::LibWebRTCMediaEndpoint::addIceCandidate):
(WebCore::LibWebRTCMediaEndpoint::OnIceCandidate):
(WebCore::LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded):
(WebCore::LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded):
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h:
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
(WebCore::LibWebRTCPeerConnectionBackend::doAddIceCandidate):
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:

LayoutTests:

Now that we update descriptions at specific times,
we need to wait a bit to get the description.

* webrtc/datachannel/mdns-ice-candidates.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectiondescriptionattributestiminghttpsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-description-attributes-timing.https-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionsetLocalDescriptionrollbackexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setLocalDescription-rollback-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebrtcdatachannelmdnsicecandidateshtml">trunk/LayoutTests/webrtc/datachannel/mdns-ice-candidates.html</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="#trunkSourceWebCoreModulesmediastreamRTCPeerConnectionh">trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/LayoutTests/ChangeLog 2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2021-09-09  Youenn Fablet  <youenn@apple.com>
+
+        Update RTCPeerConnection descriptions as per specification
+        https://bugs.webkit.org/show_bug.cgi?id=229963
+
+        Reviewed by Eric Carlson.
+
+        Now that we update descriptions at specific times,
+        we need to wait a bit to get the description.
+
+        * webrtc/datachannel/mdns-ice-candidates.html:
+
</ins><span class="cx"> 2021-09-09  Eric Hutchison  <ehutchison@apple.com>
</span><span class="cx"> 
</span><span class="cx">          [iOS14 Sim Release iPhone] fast/sub-pixel/auto-table-layout-should-avoid-text-wrapping.html is a flaky crash.
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/LayoutTests/imported/w3c/ChangeLog    2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2021-09-09  Youenn Fablet  <youenn@apple.com>
+
+        Update RTCPeerConnection descriptions as per specification
+        https://bugs.webkit.org/show_bug.cgi?id=229963
+
+        Reviewed by Eric Carlson.
+
+        * web-platform-tests/webrtc/RTCPeerConnection-description-attributes-timing.https-expected.txt:
+        * web-platform-tests/webrtc/RTCPeerConnection-setLocalDescription-rollback-expected.txt:
+
</ins><span class="cx"> 2021-09-09  Manuel Rego Casasnovas  <rego@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [css-text-decor] Update WPT test suite
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectiondescriptionattributestiminghttpsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-description-attributes-timing.https-expected.txt (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-description-attributes-timing.https-expected.txt      2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-description-attributes-timing.https-expected.txt 2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> 
</span><del>-FAIL pendingLocalDescription is surfaced at the right time assert_equals: pendingLocalDescription is still null while promise pending expected null but got object "[object RTCSessionDescription]"
-FAIL pendingRemoteDescription is surfaced at the right time assert_equals: pendingRemoteDescription is still null while promise pending expected null but got object "[object RTCSessionDescription]"
-FAIL currentLocalDescription is surfaced at the right time assert_equals: currentLocalDescription is still null while promise pending expected null but got object "[object RTCSessionDescription]"
-FAIL currentRemoteDescription is surfaced at the right time assert_equals: currentRemoteDescription is still null while promise pending expected null but got object "[object RTCSessionDescription]"
</del><ins>+PASS pendingLocalDescription is surfaced at the right time
+PASS pendingRemoteDescription is surfaced at the right time
+PASS currentLocalDescription is surfaced at the right time
+PASS currentRemoteDescription is surfaced at the right time
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebrtcRTCPeerConnectionsetLocalDescriptionrollbackexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setLocalDescription-rollback-expected.txt (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setLocalDescription-rollback-expected.txt     2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setLocalDescription-rollback-expected.txt        2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -3,5 +3,5 @@
</span><span class="cx"> PASS setLocalDescription(rollback) from stable state should reject with InvalidStateError
</span><span class="cx"> PASS setLocalDescription(rollback) after setting answer description should reject with InvalidStateError
</span><span class="cx"> PASS setLocalDescription(rollback) should ignore invalid sdp content and succeed
</span><del>-FAIL setLocalDescription(rollback) should update internal state with a queued tassk, in the right order assert_not_equals: pendingLocalDescription should not be set synchronously after a call to sLD got disallowed value null
</del><ins>+FAIL setLocalDescription(rollback) should update internal state with a queued tassk, in the right order assert_equals: pendingLocalDescription should be updated before the signalingstatechange event expected null but got object "[object RTCSessionDescription]"
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebrtcdatachannelmdnsicecandidateshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webrtc/datachannel/mdns-ice-candidates.html (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/datachannel/mdns-ice-candidates.html    2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/LayoutTests/webrtc/datachannel/mdns-ice-candidates.html       2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -160,11 +160,14 @@
</span><span class="cx"> 
</span><span class="cx">     const channel2 = pc.createDataChannel('sendDataChannel2');
</span><span class="cx">     const offer2 = await pc.createOffer();
</span><del>-    const description = pc.localDescription;
</del><span class="cx"> 
</span><span class="cx">     // Make sure we can apply the filtered description.
</span><del>-    await pc.setLocalDescription(description);
</del><ins>+    await pc.setLocalDescription(pc.localDescription);
</ins><span class="cx"> 
</span><ins>+    // Reapply description which should have candidates.
+    await pc.setLocalDescription(offer2);
+    const description = pc.localDescription;
+
</ins><span class="cx">     const lines = description.sdp.split('\r\n').filter(line => {
</span><span class="cx">         return line.indexOf('a=candidate') === 0;
</span><span class="cx">     });
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/ChangeLog      2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -1,3 +1,42 @@
</span><ins>+2021-09-09  Youenn Fablet  <youenn@apple.com>
+
+        Update RTCPeerConnection descriptions as per specification
+        https://bugs.webkit.org/show_bug.cgi?id=229963
+
+        Reviewed by Eric Carlson.
+
+        A peer connection has two sets of descriptions: main thread descriptions which are exposed to JS and signaling thread descriptions
+        which are used/modified internally by the backend.
+        WebRTC spec describes when signaling thread descriptions should be used to set main thread descriptions.
+        This should be done at the end of setting remote/local descriptions, as well as when adding or surfacing an ICE candidate.
+        We make sure to grab signaling thread descriptions at those moments, then hop to main thread to set the main thread descriptions.
+
+        In case of closed connection, we stop early as we do not need to surface new descriptions (as well as resolve promises/fire events).
+
+        Covered by rebased tests.
+
+        * Modules/mediastream/PeerConnectionBackend.cpp:
+        (WebCore::PeerConnectionBackend::setLocalDescriptionSucceeded):
+        (WebCore::PeerConnectionBackend::setRemoteDescriptionSucceeded):
+        (WebCore::PeerConnectionBackend::addIceCandidate):
+        (WebCore::PeerConnectionBackend::newICECandidate):
+        * Modules/mediastream/PeerConnectionBackend.h:
+        * Modules/mediastream/RTCPeerConnection.cpp:
+        (WebCore::updateDescription):
+        (WebCore::RTCPeerConnection::updateDescriptions):
+        * Modules/mediastream/RTCPeerConnection.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+        (WebCore::fromSessionDescriptionType):
+        (WebCore::descriptionsFromPeerConnection):
+        (WebCore::LibWebRTCMediaEndpoint::addIceCandidate):
+        (WebCore::LibWebRTCMediaEndpoint::OnIceCandidate):
+        (WebCore::LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded):
+        (WebCore::LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded):
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h:
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
+        (WebCore::LibWebRTCPeerConnectionBackend::doAddIceCandidate):
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
+
</ins><span class="cx"> 2021-09-09  Antti Koivisto  <antti@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Add cache to InlineContent for O(1) inline box access
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamPeerConnectionBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp       2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp  2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -175,16 +175,18 @@
</span><span class="cx">     doSetLocalDescription(sessionDescription);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PeerConnectionBackend::setLocalDescriptionSucceeded(std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
</del><ins>+void PeerConnectionBackend::setLocalDescriptionSucceeded(std::optional<DescriptionStates>&& descriptionStates, std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     ALWAYS_LOG(LOGIDENTIFIER);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_setDescriptionPromise);
</span><del>-    m_peerConnection.doTask([this, promise = WTFMove(m_setDescriptionPromise), sctpBackend = WTFMove(sctpBackend)]() mutable {
</del><ins>+    m_peerConnection.doTask([this, promise = WTFMove(m_setDescriptionPromise), descriptionStates = WTFMove(descriptionStates), sctpBackend = WTFMove(sctpBackend)]() mutable {
</ins><span class="cx">         if (m_peerConnection.isClosed())
</span><span class="cx">             return;
</span><span class="cx"> 
</span><ins>+        if (descriptionStates)
+            m_peerConnection.updateDescriptions(WTFMove(*descriptionStates));
</ins><span class="cx">         m_peerConnection.updateTransceiversAfterSuccessfulLocalDescription();
</span><span class="cx">         m_peerConnection.updateSctpBackend(WTFMove(sctpBackend));
</span><span class="cx">         promise->resolve();
</span><span class="lines">@@ -213,7 +215,7 @@
</span><span class="cx">     doSetRemoteDescription(sessionDescription);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
</del><ins>+void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::optional<DescriptionStates>&& descriptionStates, std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     ALWAYS_LOG(LOGIDENTIFIER, "Set remote description succeeded");
</span><span class="lines">@@ -234,10 +236,12 @@
</span><span class="cx">         track.source().setMuted(false);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_peerConnection.doTask([this, promise = WTFMove(promise), sctpBackend = WTFMove(sctpBackend)]() mutable {
</del><ins>+    m_peerConnection.doTask([this, promise = WTFMove(promise), descriptionStates = WTFMove(descriptionStates), sctpBackend = WTFMove(sctpBackend)]() mutable {
</ins><span class="cx">         if (m_peerConnection.isClosed())
</span><span class="cx">             return;
</span><span class="cx"> 
</span><ins>+        if (descriptionStates)
+            m_peerConnection.updateDescriptions(WTFMove(*descriptionStates));
</ins><span class="cx">         m_peerConnection.updateTransceiversAfterSuccessfulRemoteDescription();
</span><span class="cx">         m_peerConnection.updateSctpBackend(WTFMove(sctpBackend));
</span><span class="cx">         promise->resolve();
</span><span class="lines">@@ -314,8 +318,16 @@
</span><span class="cx">         ASSERT(isMainThread());
</span><span class="cx">         if (!weakThis || weakThis->m_peerConnection.isClosed())
</span><span class="cx">             return;
</span><del>-        RELEASE_LOG_ERROR(WebRTC, "Adding ice candidate finished, success=%d", result.hasException());
-        promise.settle(WTFMove(result));
</del><ins>+
+        if (result.hasException()) {
+            RELEASE_LOG_ERROR(WebRTC, "Adding ice candidate failed %d", result.exception().code());
+            promise.reject(result.releaseException());
+            return;
+        }
+
+        if (auto descriptions = result.releaseReturnValue())
+            weakThis->m_peerConnection.updateDescriptions(WTFMove(*descriptions));
+        promise.resolve();
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -349,12 +361,15 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PeerConnectionBackend::newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex, String&& serverURL)
</del><ins>+void PeerConnectionBackend::newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex, String&& serverURL, std::optional<DescriptionStates>&& descriptions)
</ins><span class="cx"> {
</span><del>-    m_peerConnection.doTask([logSiteIdentifier = LOGIDENTIFIER, this, sdp = WTFMove(sdp), mid = WTFMove(mid), sdpMLineIndex, serverURL = WTFMove(serverURL)]() mutable {
</del><ins>+    m_peerConnection.doTask([logSiteIdentifier = LOGIDENTIFIER, this, sdp = WTFMove(sdp), mid = WTFMove(mid), sdpMLineIndex, serverURL = WTFMove(serverURL), descriptions = WTFMove(descriptions)]() mutable {
</ins><span class="cx">         if (m_peerConnection.isClosed())
</span><span class="cx">             return;
</span><span class="cx"> 
</span><ins>+        if (descriptions)
+            m_peerConnection.updateDescriptions(WTFMove(*descriptions));
+
</ins><span class="cx">         UNUSED_PARAM(logSiteIdentifier);
</span><span class="cx">         ALWAYS_LOG(logSiteIdentifier, "Gathered ice candidate:", sdp);
</span><span class="cx">         m_finishedGatheringCandidates = false;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamPeerConnectionBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h 2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h    2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -104,14 +104,6 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void close() = 0;
</span><span class="cx"> 
</span><del>-    virtual RefPtr<RTCSessionDescription> localDescription() const = 0;
-    virtual RefPtr<RTCSessionDescription> currentLocalDescription() const = 0;
-    virtual RefPtr<RTCSessionDescription> pendingLocalDescription() const = 0;
-
-    virtual RefPtr<RTCSessionDescription> remoteDescription() const = 0;
-    virtual RefPtr<RTCSessionDescription> currentRemoteDescription() const = 0;
-    virtual RefPtr<RTCSessionDescription> pendingRemoteDescription() const = 0;
-
</del><span class="cx">     virtual void restartIce() = 0;
</span><span class="cx">     virtual bool setConfiguration(MediaEndpointConfiguration&&) = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -130,7 +122,18 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void emulatePlatformEvent(const String& action) = 0;
</span><span class="cx"> 
</span><del>-    void newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex, String&& serverURL);
</del><ins>+    struct DescriptionStates {
+        std::optional<RTCSdpType> currentLocalDescriptionSdpType;
+        String currentLocalDescriptionSdp;
+        std::optional<RTCSdpType> pendingLocalDescriptionSdpType;
+        String pendingLocalDescriptionSdp;
+        std::optional<RTCSdpType> currentRemoteDescriptionSdpType;
+        String currentRemoteDescriptionSdp;
+        std::optional<RTCSdpType> pendingRemoteDescriptionSdpType;
+        String pendingRemoteDescriptionSdp;
+    };
+
+    void newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex, String&& serverURL, std::optional<DescriptionStates>&&);
</ins><span class="cx">     virtual void disableICECandidateFiltering();
</span><span class="cx">     void enableICECandidateFiltering();
</span><span class="cx"> 
</span><span class="lines">@@ -187,6 +190,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool shouldFilterICECandidates() const { return m_shouldFilterICECandidates; };
</span><span class="cx"> 
</span><ins>+    using AddIceCandidateCallbackFunction = void(ExceptionOr<std::optional<PeerConnectionBackend::DescriptionStates>>&&);
+    using AddIceCandidateCallback = Function<AddIceCandidateCallbackFunction>;
+
</ins><span class="cx"> protected:
</span><span class="cx">     void fireICECandidateEvent(RefPtr<RTCIceCandidate>&&, String&& url);
</span><span class="cx">     void doneGatheringCandidates();
</span><span class="lines">@@ -199,15 +205,12 @@
</span><span class="cx">     void createAnswerSucceeded(String&&);
</span><span class="cx">     void createAnswerFailed(Exception&&);
</span><span class="cx"> 
</span><del>-    void setLocalDescriptionSucceeded(std::unique_ptr<RTCSctpTransportBackend>&&);
</del><ins>+    void setLocalDescriptionSucceeded(std::optional<DescriptionStates>&&, std::unique_ptr<RTCSctpTransportBackend>&&);
</ins><span class="cx">     void setLocalDescriptionFailed(Exception&&);
</span><span class="cx"> 
</span><del>-    void setRemoteDescriptionSucceeded(std::unique_ptr<RTCSctpTransportBackend>&&);
</del><ins>+    void setRemoteDescriptionSucceeded(std::optional<DescriptionStates>&&, std::unique_ptr<RTCSctpTransportBackend>&&);
</ins><span class="cx">     void setRemoteDescriptionFailed(Exception&&);
</span><span class="cx"> 
</span><del>-    void addIceCandidateSucceeded();
-    void addIceCandidateFailed(Exception&&);
-
</del><span class="cx">     void validateSDP(const String&) const;
</span><span class="cx"> 
</span><span class="cx">     struct PendingTrackEvent {
</span><span class="lines">@@ -223,7 +226,7 @@
</span><span class="cx">     virtual void doCreateAnswer(RTCAnswerOptions&&) = 0;
</span><span class="cx">     virtual void doSetLocalDescription(const RTCSessionDescription*) = 0;
</span><span class="cx">     virtual void doSetRemoteDescription(const RTCSessionDescription&) = 0;
</span><del>-    virtual void doAddIceCandidate(RTCIceCandidate&, Function<void(ExceptionOr<void>&&)>&&) = 0;
</del><ins>+    virtual void doAddIceCandidate(RTCIceCandidate&, AddIceCandidateCallback&&) = 0;
</ins><span class="cx">     virtual void endOfIceCandidates(DOMPromiseDeferred<void>&&);
</span><span class="cx">     virtual void doStop() = 0;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCPeerConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp   2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp      2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -247,21 +247,6 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<RTCSessionDescription> RTCPeerConnection::localDescription() const
-{
-    return m_backend->localDescription();
-}
-
-RefPtr<RTCSessionDescription> RTCPeerConnection::currentLocalDescription() const
-{
-    return m_backend->currentLocalDescription();
-}
-
-RefPtr<RTCSessionDescription> RTCPeerConnection::pendingLocalDescription() const
-{
-    return m_backend->pendingLocalDescription();
-}
-
</del><span class="cx"> void RTCPeerConnection::setRemoteDescription(Description&& remoteDescription, Ref<DeferredPromise>&& promise)
</span><span class="cx"> {
</span><span class="cx">     RefPtr<RTCSessionDescription> description;
</span><span class="lines">@@ -286,21 +271,6 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<RTCSessionDescription> RTCPeerConnection::remoteDescription() const
-{
-    return m_backend->remoteDescription();
-}
-
-RefPtr<RTCSessionDescription> RTCPeerConnection::currentRemoteDescription() const
-{
-    return m_backend->currentRemoteDescription();
-}
-
-RefPtr<RTCSessionDescription> RTCPeerConnection::pendingRemoteDescription() const
-{
-    return m_backend->pendingRemoteDescription();
-}
-
</del><span class="cx"> void RTCPeerConnection::addIceCandidate(Candidate&& rtcCandidate, Ref<DeferredPromise>&& promise)
</span><span class="cx"> {
</span><span class="cx">     std::optional<Exception> exception;
</span><span class="lines">@@ -934,6 +904,25 @@
</span><span class="cx">     return m_dtlsTransports[index].copyRef();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void updateDescription(RefPtr<RTCSessionDescription>& description, std::optional<RTCSdpType> type, String&& sdp)
+{
+    if (description && type && description->sdp() == sdp && description->type() == *type)
+        return;
+    if (!type || sdp.isEmpty()) {
+        description = nullptr;
+        return;
+    }
+    description = RTCSessionDescription::create(*type, WTFMove(sdp));
+}
+
+void RTCPeerConnection::updateDescriptions(PeerConnectionBackend::DescriptionStates&& states)
+{
+    updateDescription(m_currentLocalDescription, states.currentLocalDescriptionSdpType, WTFMove(states.currentLocalDescriptionSdp));
+    updateDescription(m_pendingLocalDescription, states.pendingLocalDescriptionSdpType, WTFMove(states.pendingLocalDescriptionSdp));
+    updateDescription(m_currentRemoteDescription, states.currentRemoteDescriptionSdpType, WTFMove(states.currentRemoteDescriptionSdp));
+    updateDescription(m_pendingRemoteDescription, states.pendingRemoteDescriptionSdpType, WTFMove(states.pendingRemoteDescriptionSdp));
+}
+
</ins><span class="cx"> void RTCPeerConnection::updateTransceiverTransports()
</span><span class="cx"> {
</span><span class="cx">     for (auto& transceiver : m_transceiverSet.list()) {
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCPeerConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h     2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h        2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -112,14 +112,14 @@
</span><span class="cx"> 
</span><span class="cx">     using Description = Variant<RTCSessionDescriptionInit, RefPtr<RTCSessionDescription>>;
</span><span class="cx">     void setLocalDescription(std::optional<Description>&&, Ref<DeferredPromise>&&);
</span><del>-    RefPtr<RTCSessionDescription> localDescription() const;
-    RefPtr<RTCSessionDescription> currentLocalDescription() const;
-    RefPtr<RTCSessionDescription> pendingLocalDescription() const;
</del><ins>+    RefPtr<RTCSessionDescription> localDescription() const { return m_pendingLocalDescription ? m_pendingLocalDescription.get() : m_currentLocalDescription.get(); }
+    RefPtr<RTCSessionDescription> currentLocalDescription() const { return m_currentLocalDescription.get(); }
+    RefPtr<RTCSessionDescription> pendingLocalDescription() const { return m_pendingLocalDescription.get(); }
</ins><span class="cx"> 
</span><span class="cx">     void setRemoteDescription(Description&&, Ref<DeferredPromise>&&);
</span><del>-    RefPtr<RTCSessionDescription> remoteDescription() const;
-    RefPtr<RTCSessionDescription> currentRemoteDescription() const;
-    RefPtr<RTCSessionDescription> pendingRemoteDescription() const;
</del><ins>+    RTCSessionDescription* remoteDescription() const { return m_pendingRemoteDescription ? m_pendingRemoteDescription.get() : m_currentRemoteDescription.get(); }
+    RTCSessionDescription* currentRemoteDescription() const { return m_currentRemoteDescription.get(); }
+    RTCSessionDescription* pendingRemoteDescription() const { return m_pendingRemoteDescription.get(); }
</ins><span class="cx"> 
</span><span class="cx">     using Candidate = std::optional<Variant<RTCIceCandidateInit, RefPtr<RTCIceCandidate>>>;
</span><span class="cx">     void addIceCandidate(Candidate&&, Ref<DeferredPromise>&&);
</span><span class="lines">@@ -187,6 +187,7 @@
</span><span class="cx"> 
</span><span class="cx">     void doTask(Function<void()>&&);
</span><span class="cx"> 
</span><ins>+    void updateDescriptions(PeerConnectionBackend::DescriptionStates&&);
</ins><span class="cx">     void updateTransceiversAfterSuccessfulLocalDescription();
</span><span class="cx">     void updateTransceiversAfterSuccessfulRemoteDescription();
</span><span class="cx">     void updateSctpBackend(std::unique_ptr<RTCSctpTransportBackend>&&);
</span><span class="lines">@@ -271,6 +272,11 @@
</span><span class="cx">     Vector<Ref<RTCDtlsTransport>> m_dtlsTransports;
</span><span class="cx">     Vector<Ref<RTCIceTransport>> m_iceTransports;
</span><span class="cx">     RefPtr<RTCSctpTransport> m_sctpTransport;
</span><ins>+
+    RefPtr<RTCSessionDescription> m_currentLocalDescription;
+    RefPtr<RTCSessionDescription> m_pendingLocalDescription;
+    RefPtr<RTCSessionDescription> m_currentRemoteDescription;
+    RefPtr<RTCSessionDescription> m_pendingRemoteDescription;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp    2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp       2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx"> #include <webrtc/pc/peer_connection_factory.h>
</span><span class="cx"> #include <webrtc/system_wrappers/include/field_trial.h>
</span><span class="cx"> #include <wtf/MainThread.h>
</span><ins>+#include <wtf/SharedTask.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -143,59 +144,6 @@
</span><span class="cx">     return "";
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline RTCSdpType fromSessionDescriptionType(const webrtc::SessionDescriptionInterface& description)
-{
-    auto type = description.type();
-    if (type == webrtc::SessionDescriptionInterface::kOffer)
-        return RTCSdpType::Offer;
-    if (type == webrtc::SessionDescriptionInterface::kAnswer)
-        return RTCSdpType::Answer;
-    ASSERT(type == webrtc::SessionDescriptionInterface::kPrAnswer);
-    return RTCSdpType::Pranswer;
-}
-
-static inline RefPtr<RTCSessionDescription> fromSessionDescription(const webrtc::SessionDescriptionInterface* description)
-{
-    if (!description)
-        return nullptr;
-
-    std::string sdp;
-    description->ToString(&sdp);
-
-    return RTCSessionDescription::create(fromSessionDescriptionType(*description), fromStdString(sdp));
-}
-
-// FIXME: We might want to create a new object only if the session actually changed for all description getters.
-RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::currentLocalDescription() const
-{
-    return m_backend ? fromSessionDescription(m_backend->current_local_description()) : nullptr;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::currentRemoteDescription() const
-{
-    return m_backend ? fromSessionDescription(m_backend->current_remote_description()) : nullptr;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::pendingLocalDescription() const
-{
-    return m_backend ? fromSessionDescription(m_backend->pending_local_description()) : nullptr;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::pendingRemoteDescription() const
-{
-    return m_backend ? fromSessionDescription(m_backend->pending_remote_description()) : nullptr;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::localDescription() const
-{
-    return m_backend ? fromSessionDescription(m_backend->local_description()) : nullptr;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::remoteDescription() const
-{
-    return m_backend ? fromSessionDescription(m_backend->remote_description()) : nullptr;
-}
-
</del><span class="cx"> void LibWebRTCMediaEndpoint::doSetLocalDescription(const RTCSessionDescription* description)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_backend);
</span><span class="lines">@@ -620,11 +568,62 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void LibWebRTCMediaEndpoint::addIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface>&& candidate, std::function<void(webrtc::RTCError)>&& callback)
</del><ins>+static inline RTCSdpType fromSessionDescriptionType(const webrtc::SessionDescriptionInterface& description)
</ins><span class="cx"> {
</span><del>-    m_backend->AddIceCandidate(WTFMove(candidate), WTFMove(callback));
</del><ins>+    auto type = description.type();
+    if (type == webrtc::SessionDescriptionInterface::kOffer)
+        return RTCSdpType::Offer;
+    if (type == webrtc::SessionDescriptionInterface::kAnswer)
+        return RTCSdpType::Answer;
+    ASSERT(type == webrtc::SessionDescriptionInterface::kPrAnswer);
+    return RTCSdpType::Pranswer;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static std::optional<PeerConnectionBackend::DescriptionStates> descriptionsFromPeerConnection(webrtc::PeerConnectionInterface* connection)
+{
+    if (!connection)
+        return { };
+
+    std::optional<RTCSdpType> currentLocalDescriptionSdpType, pendingLocalDescriptionSdpType, currentRemoteDescriptionSdpType, pendingRemoteDescriptionSdpType;
+    std::string currentLocalDescriptionSdp, pendingLocalDescriptionSdp, currentRemoteDescriptionSdp, pendingRemoteDescriptionSdp;
+    if (auto* description = connection->current_local_description()) {
+        currentLocalDescriptionSdpType = fromSessionDescriptionType(*description);
+        description->ToString(&currentLocalDescriptionSdp);
+    }
+    if (auto* description = connection->pending_local_description()) {
+        pendingLocalDescriptionSdpType = fromSessionDescriptionType(*description);
+        description->ToString(&pendingLocalDescriptionSdp);
+    }
+    if (auto* description = connection->current_remote_description()) {
+        currentRemoteDescriptionSdpType = fromSessionDescriptionType(*description);
+        description->ToString(&currentRemoteDescriptionSdp);
+    }
+    if (auto* description = connection->pending_remote_description()) {
+        pendingRemoteDescriptionSdpType = fromSessionDescriptionType(*description);
+        description->ToString(&pendingRemoteDescriptionSdp);
+    }
+
+    return PeerConnectionBackend::DescriptionStates {
+        currentLocalDescriptionSdpType, fromStdString(currentLocalDescriptionSdp),
+        pendingLocalDescriptionSdpType, fromStdString(pendingLocalDescriptionSdp),
+        currentRemoteDescriptionSdpType, fromStdString(currentRemoteDescriptionSdp),
+        pendingRemoteDescriptionSdpType, fromStdString(pendingRemoteDescriptionSdp)
+    };
+}
+
+void LibWebRTCMediaEndpoint::addIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface>&& candidate, PeerConnectionBackend::AddIceCandidateCallback&& callback)
+{
+    m_backend->AddIceCandidate(WTFMove(candidate), [task = createSharedTask<PeerConnectionBackend::AddIceCandidateCallbackFunction>(WTFMove(callback)), backend = m_backend](auto&& error) mutable {
+        callOnMainThread([task = WTFMove(task), descriptions = descriptionsFromPeerConnection(backend.get()), error = WTFMove(error)]() mutable {
+            if (!error.ok()) {
+                task->run(toException(error));
+                return;
+            }
+            task->run(WTFMove(descriptions));
+        });
+    });
+}
+
</ins><span class="cx"> void LibWebRTCMediaEndpoint::OnIceCandidate(const webrtc::IceCandidateInterface *rtcCandidate)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(rtcCandidate);
</span><span class="lines">@@ -634,10 +633,10 @@
</span><span class="cx"> 
</span><span class="cx">     auto sdpMLineIndex = safeCast<unsigned short>(rtcCandidate->sdp_mline_index());
</span><span class="cx"> 
</span><del>-    callOnMainThread([protectedThis = makeRef(*this), mid = fromStdString(rtcCandidate->sdp_mid()), sdp = fromStdString(sdp), sdpMLineIndex, url = fromStdString(rtcCandidate->server_url())]() mutable {
</del><ins>+    callOnMainThread([protectedThis = makeRef(*this), descriptions = descriptionsFromPeerConnection(m_backend.get()), mid = fromStdString(rtcCandidate->sdp_mid()), sdp = fromStdString(sdp), sdpMLineIndex, url = fromStdString(rtcCandidate->server_url())]() mutable {
</ins><span class="cx">         if (protectedThis->isStopped())
</span><span class="cx">             return;
</span><del>-        protectedThis->m_peerConnectionBackend.newICECandidate(WTFMove(sdp), WTFMove(mid), sdpMLineIndex, WTFMove(url));
</del><ins>+        protectedThis->m_peerConnectionBackend.newICECandidate(WTFMove(sdp), WTFMove(mid), sdpMLineIndex, WTFMove(url), WTFMove(descriptions));
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -699,10 +698,10 @@
</span><span class="cx"> 
</span><span class="cx"> void LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded()
</span><span class="cx"> {
</span><del>-    callOnMainThread([protectedThis = makeRef(*this), sctpState = SctpTransportState(m_backend->GetSctpTransport())]() mutable {
</del><ins>+    callOnMainThread([protectedThis = makeRef(*this), descriptions = descriptionsFromPeerConnection(m_backend.get()), sctpState = SctpTransportState(m_backend->GetSctpTransport())]() mutable {
</ins><span class="cx">         if (protectedThis->isStopped())
</span><span class="cx">             return;
</span><del>-        protectedThis->m_peerConnectionBackend.setLocalDescriptionSucceeded(sctpState.createBackend());
</del><ins>+        protectedThis->m_peerConnectionBackend.setLocalDescriptionSucceeded(WTFMove(descriptions), sctpState.createBackend());
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -717,10 +716,10 @@
</span><span class="cx"> 
</span><span class="cx"> void LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded()
</span><span class="cx"> {
</span><del>-    callOnMainThread([protectedThis = makeRef(*this), sctpState = SctpTransportState(m_backend->GetSctpTransport())]() mutable {
</del><ins>+    callOnMainThread([protectedThis = makeRef(*this), descriptions = descriptionsFromPeerConnection(m_backend.get()), sctpState = SctpTransportState(m_backend->GetSctpTransport())]() mutable {
</ins><span class="cx">         if (protectedThis->isStopped())
</span><span class="cx">             return;
</span><del>-        protectedThis->m_peerConnectionBackend.setRemoteDescriptionSucceeded(sctpState.createBackend());
</del><ins>+        protectedThis->m_peerConnectionBackend.setRemoteDescriptionSucceeded(WTFMove(descriptions), sctpState.createBackend());
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h      2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h 2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -89,19 +89,12 @@
</span><span class="cx">     void getStats(webrtc::RtpReceiverInterface&, Ref<DeferredPromise>&&);
</span><span class="cx">     void getStats(webrtc::RtpSenderInterface&, Ref<DeferredPromise>&&);
</span><span class="cx">     std::unique_ptr<RTCDataChannelHandler> createDataChannel(const String&, const RTCDataChannelInit&);
</span><del>-    void addIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface>&&, std::function<void(webrtc::RTCError)>&&);
</del><ins>+    void addIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface>&&, PeerConnectionBackend::AddIceCandidateCallback&&);
</ins><span class="cx"> 
</span><span class="cx">     void close();
</span><span class="cx">     void stop();
</span><span class="cx">     bool isStopped() const { return !m_backend; }
</span><span class="cx"> 
</span><del>-    RefPtr<RTCSessionDescription> localDescription() const;
-    RefPtr<RTCSessionDescription> remoteDescription() const;
-    RefPtr<RTCSessionDescription> currentLocalDescription() const;
-    RefPtr<RTCSessionDescription> currentRemoteDescription() const;
-    RefPtr<RTCSessionDescription> pendingLocalDescription() const;
-    RefPtr<RTCSessionDescription> pendingRemoteDescription() const;
-
</del><span class="cx">     bool addTrack(LibWebRTCRtpSenderBackend&, MediaStreamTrack&, const Vector<String>&);
</span><span class="cx">     void removeTrack(LibWebRTCRtpSenderBackend&);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp    2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp       2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -47,7 +47,6 @@
</span><span class="cx"> #include "RealtimeOutgoingAudioSource.h"
</span><span class="cx"> #include "RealtimeOutgoingVideoSource.h"
</span><span class="cx"> #include "Settings.h"
</span><del>-#include <wtf/SharedTask.h>
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -270,7 +269,7 @@
</span><span class="cx">     m_pendingReceivers.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void LibWebRTCPeerConnectionBackend::doAddIceCandidate(RTCIceCandidate& candidate, Function<void(ExceptionOr<void>&&)>&& callback)
</del><ins>+void LibWebRTCPeerConnectionBackend::doAddIceCandidate(RTCIceCandidate& candidate, AddIceCandidateCallback&& callback)
</ins><span class="cx"> {
</span><span class="cx">     webrtc::SdpParseError error;
</span><span class="cx">     int sdpMLineIndex = candidate.sdpMLineIndex() ? candidate.sdpMLineIndex().value() : 0;
</span><span class="lines">@@ -281,15 +280,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_endpoint->addIceCandidate(WTFMove(rtcCandidate), [task = createSharedTask<void(ExceptionOr<void>&&)>(WTFMove(callback))](auto&& error) mutable {
-        callOnMainThread([task = WTFMove(task), error = WTFMove(error)] {
-            if (!error.ok()) {
-                task->run(toException(error));
-                return;
-            }
-            task->run({ });
-        });
-    });
</del><ins>+    m_endpoint->addIceCandidate(WTFMove(rtcCandidate), WTFMove(callback));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref<RTCRtpReceiver> LibWebRTCPeerConnectionBackend::createReceiver(std::unique_ptr<LibWebRTCRtpReceiverBackend>&& backend)
</span><span class="lines">@@ -311,45 +302,6 @@
</span><span class="cx">     return m_endpoint->createDataChannel(label, options);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::currentLocalDescription() const
-{
-    auto description = m_endpoint->currentLocalDescription();
-    if (description)
-        validateSDP(description->sdp());
-    return description;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::currentRemoteDescription() const
-{
-    return m_endpoint->currentRemoteDescription();
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::pendingLocalDescription() const
-{
-    auto description = m_endpoint->pendingLocalDescription();
-    if (description)
-        validateSDP(description->sdp());
-    return description;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::pendingRemoteDescription() const
-{
-    return m_endpoint->pendingRemoteDescription();
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::localDescription() const
-{
-    auto description = m_endpoint->localDescription();
-    if (description)
-        validateSDP(description->sdp());
-    return description;
-}
-
-RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::remoteDescription() const
-{
-    return m_endpoint->remoteDescription();
-}
-
</del><span class="cx"> static inline RefPtr<RTCRtpSender> findExistingSender(const Vector<RefPtr<RTCRtpTransceiver>>& transceivers, LibWebRTCRtpSenderBackend& senderBackend)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(senderBackend.rtcSender());
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h (282216 => 282217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h      2021-09-09 15:57:27 UTC (rev 282216)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h 2021-09-09 16:08:51 UTC (rev 282217)
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">     void doCreateAnswer(RTCAnswerOptions&&) final;
</span><span class="cx">     void doSetLocalDescription(const RTCSessionDescription*) final;
</span><span class="cx">     void doSetRemoteDescription(const RTCSessionDescription&) final;
</span><del>-    void doAddIceCandidate(RTCIceCandidate&, Function<void(ExceptionOr<void>&&)>&&) final;
</del><ins>+    void doAddIceCandidate(RTCIceCandidate&, AddIceCandidateCallback&&) final;
</ins><span class="cx">     void doStop() final;
</span><span class="cx">     std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) final;
</span><span class="cx">     void restartIce() final;
</span><span class="lines">@@ -71,14 +71,6 @@
</span><span class="cx">     void getStats(RTCRtpSender&, Ref<DeferredPromise>&&) final;
</span><span class="cx">     void getStats(RTCRtpReceiver&, Ref<DeferredPromise>&&) final;
</span><span class="cx"> 
</span><del>-    RefPtr<RTCSessionDescription> localDescription() const final;
-    RefPtr<RTCSessionDescription> currentLocalDescription() const final;
-    RefPtr<RTCSessionDescription> pendingLocalDescription() const final;
-
-    RefPtr<RTCSessionDescription> remoteDescription() const final;
-    RefPtr<RTCSessionDescription> currentRemoteDescription() const final;
-    RefPtr<RTCSessionDescription> pendingRemoteDescription() const final;
-
</del><span class="cx">     std::optional<bool> canTrickleIceCandidates() const final;
</span><span class="cx"> 
</span><span class="cx">     void emulatePlatformEvent(const String&) final { }
</span></span></pre>
</div>
</div>

</body>
</html>