<!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>[214350] 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/214350">214350</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-03-24 09:32:53 -0700 (Fri, 24 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for DataChannel and MediaStreamTrack stats
https://bugs.webkit.org/show_bug.cgi?id=170031

Patch by Youenn Fablet &lt;youenn@apple.com&gt; on 2017-03-24
Reviewed by Eric Carlson.

Source/WebCore:

Tests: webrtc/datachannel/datachannel-stats.html
       webrtc/video-mediastreamtrack-stats.html

Exposing libwebrtc stats through WebRTC stats API, gathered for data channel and media stream tracks.

* Modules/mediastream/RTCStatsReport.h:
(WebCore::RTCStatsReport::MediaStreamTrackStats::MediaStreamTrackStats):
(WebCore::RTCStatsReport::DataChannelStats::DataChannelStats):
* Modules/mediastream/RTCStatsReport.idl:
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::fillRTCMediaStreamTrackStats):
(WebCore::fillRTCDataChannelStats):
(WebCore::LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered):

LayoutTests:

* webrtc/datachannel/datachannel-stats-expected.txt: Added.
* webrtc/datachannel/datachannel-stats.html: Added.
* webrtc/video-mediastreamtrack-stats-expected.txt: Added.
* webrtc/video-mediastreamtrack-stats.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCStatsReporth">trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCStatsReportidl">trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestswebrtcdatachanneldatachannelstatsexpectedtxt">trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebrtcdatachanneldatachannelstatshtml">trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html</a></li>
<li><a href="#trunkLayoutTestswebrtcvideomediastreamtrackstatsexpectedtxt">trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebrtcvideomediastreamtrackstatshtml">trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (214349 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/LayoutTests/ChangeLog        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2017-03-24  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        Add support for DataChannel and MediaStreamTrack stats
+        https://bugs.webkit.org/show_bug.cgi?id=170031
+
+        Reviewed by Eric Carlson.
+
+        * webrtc/datachannel/datachannel-stats-expected.txt: Added.
+        * webrtc/datachannel/datachannel-stats.html: Added.
+        * webrtc/video-mediastreamtrack-stats-expected.txt: Added.
+        * webrtc/video-mediastreamtrack-stats.html: Added.
+
</ins><span class="cx"> 2017-03-24  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Extend svg/animations/animations-paused-disconnected-iframe.html
</span></span></pre></div>
<a id="trunkLayoutTestswebrtcdatachanneldatachannelstatsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt (0 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt                                (rev 0)
+++ trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASS Basic data channel exchange with stats 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebrtcdatachanneldatachannelstatshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html (0 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html                                (rev 0)
+++ trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -0,0 +1,87 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;meta charset=&quot;utf-8&quot;&gt;
+    &lt;title&gt;Testing basic data channel from offerer to receiver&lt;/title&gt;
+    &lt;script src=&quot;../../resources/testharness.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;../../resources/testharnessreport.js&quot;&gt;&lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body&gt;
+    &lt;script src =&quot;../routines.js&quot;&gt;&lt;/script&gt;
+    &lt;script&gt;
+var localChannel;
+var remoteChannel;
+
+function receiveMessages(event) {
+    if (++counter === 1)
+        assert_equals(event.data, &quot;one&quot;);
+    else if (counter === 2)
+        assert_equals(event.data, &quot;two&quot;);
+    else if (counter === 3)
+        assert_equals(event.data, &quot;three&quot;);
+    else if (counter === 4) {
+        assert_equals(event.data, &quot;four&quot;);
+        finishTest();
+    } else
+        assert_unreached();
+}
+
+function sendMessages(channel)
+{
+    channel.send(&quot;one&quot;);
+    channel.send(&quot;two&quot;);
+    channel.send(&quot;three&quot;);
+    channel.send(&quot;four&quot;);
+}
+
+function getDataChannelStats(connection)
+{
+    return connection.getStats().then((report) =&gt; {
+        var stats;
+        report.forEach((statItem) =&gt; {
+            if (statItem.type === &quot;data-channel&quot;) {
+                stats = statItem;
+            }
+        });
+        return stats;
+    });
+}
+
+var finishTest;
+promise_test((test) =&gt; {
+    counter = 0;
+    return new Promise((resolve, reject) =&gt; {
+        if (window.internals)
+            internals.useMockRTCPeerConnectionFactory(&quot;TwoRealPeerConnections&quot;);
+
+        var localConnection, remoteConnection;
+        finishTest = () =&gt; {
+            getDataChannelStats(localConnection).then((stats) =&gt; {
+                stats.id = &quot;id&quot;;
+                stats.timestamp = 1;
+                assert_equals(JSON.stringify(stats), '{&quot;id&quot;:&quot;id&quot;,&quot;timestamp&quot;:1,&quot;type&quot;:&quot;data-channel&quot;,&quot;bytesReceived&quot;:0,&quot;bytesSent&quot;:15,&quot;datachannelid&quot;:1,&quot;label&quot;:&quot;sendDataChannel&quot;,&quot;messagesReceived&quot;:0,&quot;messagesSent&quot;:4,&quot;protocol&quot;:&quot;&quot;,&quot;state&quot;:&quot;open&quot;}');
+                return getDataChannelStats(remoteConnection);
+            }).then((stats) =&gt; {
+                stats.id = &quot;id&quot;;
+                stats.timestamp = 1;
+                assert_equals(JSON.stringify(stats), '{&quot;id&quot;:&quot;id&quot;,&quot;timestamp&quot;:1,&quot;type&quot;:&quot;data-channel&quot;,&quot;bytesReceived&quot;:15,&quot;bytesSent&quot;:0,&quot;datachannelid&quot;:1,&quot;label&quot;:&quot;sendDataChannel&quot;,&quot;messagesReceived&quot;:4,&quot;messagesSent&quot;:0,&quot;protocol&quot;:&quot;&quot;,&quot;state&quot;:&quot;open&quot;}');
+                 resolve();
+            });
+        };
+
+        createConnections((connection) =&gt; {
+            localConnection = connection;
+            localChannel = localConnection.createDataChannel('sendDataChannel');
+            localChannel.onopen = () =&gt; { sendMessages(localChannel) };
+        }, (connection) =&gt; {
+            remoteConnection = connection;
+            remoteConnection.ondatachannel = (event) =&gt; {
+                remoteChannel = event.channel;
+                remoteChannel.onmessage = receiveMessages;
+            };
+        });
+    });
+}, &quot;Basic data channel exchange with stats&quot;);
+    &lt;/script&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestswebrtcvideomediastreamtrackstatsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt (0 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt                                (rev 0)
+++ trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASS Basic video media stream track stats 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebrtcvideomediastreamtrackstatshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html (0 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html                                (rev 0)
+++ trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;meta charset=&quot;utf-8&quot;&gt;
+        &lt;title&gt;Testing basic video exchange from offerer to receiver&lt;/title&gt;
+        &lt;script src=&quot;../resources/testharness.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;../resources/testharnessreport.js&quot;&gt;&lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body&gt;
+        &lt;script src =&quot;routines.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+function getTrackStats(connection)
+{
+    return connection.getStats().then((report) =&gt; {
+        var stats;
+        report.forEach((statItem) =&gt; {
+            if (statItem.type === &quot;track&quot;) {
+                stats = statItem;
+            }
+        });
+        return stats;
+    });
+}
+
+var firstConnection, secondConnection;
+promise_test((test) =&gt; {
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+
+    var localStream, remoteStream;
+    return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) =&gt; {
+        localStream = stream;
+        return new Promise((resolve, reject) =&gt; {
+            if (window.internals)
+                internals.useMockRTCPeerConnectionFactory(&quot;TwoRealPeerConnections&quot;);
+
+            createConnections((connection) =&gt; {
+                firstConnection = connection;
+                firstConnection.addTrack(stream.getVideoTracks()[0], stream);
+            }, (connection) =&gt; {
+                secondConnection = connection;
+                secondConnection.ontrack = (trackEvent) =&gt; {
+                    remoteStream = trackEvent.streams[0];
+                    resolve();
+                };
+            });
+            setTimeout(() =&gt; reject(&quot;Test timed out&quot;), 5000);
+        });
+    }).then(() =&gt; {
+        return getTrackStats(secondConnection);
+    }).then((stats) =&gt; {
+        assert_true(!!stats, &quot;tracks stats should not be null or undefined&quot;);
+        stats.id = &quot;id&quot;;
+        stats.timestamp = 1;
+        stats.trackIdentifier = &quot;trackid&quot;;
+        assert_equals(JSON.stringify(stats), '{&quot;id&quot;:&quot;id&quot;,&quot;timestamp&quot;:1,&quot;type&quot;:&quot;track&quot;,&quot;audioLevel&quot;:0,&quot;detached&quot;:false,&quot;echoReturnLoss&quot;:0,&quot;echoReturnLossEnhancement&quot;:0,&quot;ended&quot;:false,&quot;frameHeight&quot;:0,&quot;frameWidth&quot;:0,&quot;framesCorrupted&quot;:0,&quot;framesDecoded&quot;:0,&quot;framesDropped&quot;:0,&quot;framesPerSecond&quot;:0,&quot;framesReceived&quot;:0,&quot;framesSent&quot;:0,&quot;fullFramesLost&quot;:0,&quot;partialFramesLost&quot;:0,&quot;remoteSource&quot;:true,&quot;trackIdentifier&quot;:&quot;trackid&quot;}');
+        return waitFor(1000);
+    }).then(() =&gt; {
+        return getTrackStats(secondConnection);
+    }).then((stats) =&gt; {
+        assert_equals(stats.frameHeight, 480);
+        assert_equals(stats.frameWidth, 640);
+        assert_true(stats.framesDecoded &gt; 0);
+        assert_true(stats.framesReceived &gt; 0);
+    });
+}, &quot;Basic video media stream track stats&quot;);
+        &lt;/script&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (214349 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/ChangeLog        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -1,5 +1,26 @@
</span><span class="cx"> 2017-03-24  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Add support for DataChannel and MediaStreamTrack stats
+        https://bugs.webkit.org/show_bug.cgi?id=170031
+
+        Reviewed by Eric Carlson.
+
+        Tests: webrtc/datachannel/datachannel-stats.html
+               webrtc/video-mediastreamtrack-stats.html
+
+        Exposing libwebrtc stats through WebRTC stats API, gathered for data channel and media stream tracks.
+
+        * Modules/mediastream/RTCStatsReport.h:
+        (WebCore::RTCStatsReport::MediaStreamTrackStats::MediaStreamTrackStats):
+        (WebCore::RTCStatsReport::DataChannelStats::DataChannelStats):
+        * Modules/mediastream/RTCStatsReport.idl:
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+        (WebCore::fillRTCMediaStreamTrackStats):
+        (WebCore::fillRTCDataChannelStats):
+        (WebCore::LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered):
+
+2017-03-24  Youenn Fablet  &lt;youenn@apple.com&gt;
+
</ins><span class="cx">         Fix framesEncoded/framesDecoded RTC stats
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=170024
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCStatsReporth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h (214349 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h        2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -116,6 +116,41 @@
</span><span class="cx">         unsigned long framesEncoded { 0 };
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    struct MediaStreamTrackStats : Stats {
+        MediaStreamTrackStats() { type = RTCStatsReport::Type::Track; }
+
+        String trackIdentifier;
+        bool remoteSource { false };
+        bool ended { false };
+        bool detached { false };
+        unsigned long frameWidth { 0 };
+        unsigned long frameHeight { 0};
+        double framesPerSecond { 0 };
+        unsigned long framesSent { 0 };
+        unsigned long framesReceived { 0 };
+        unsigned long framesDecoded { 0 };
+        unsigned long framesDropped { 0 };
+        unsigned long framesCorrupted { 0 };
+        unsigned long partialFramesLost { 0 };
+        unsigned long fullFramesLost { 0 };
+        double audioLevel { 0 };
+        double echoReturnLoss { 0 };
+        double echoReturnLossEnhancement { 0 };
+    };
+
+    struct DataChannelStats : Stats {
+        DataChannelStats() { type = RTCStatsReport::Type::DataChannel; }
+        
+        String label;
+        String protocol;
+        long datachannelid { 0 };
+        String state;
+        unsigned long messagesSent { 0 };
+        unsigned long long bytesSent { 0 };
+        unsigned long messagesReceived { 0 };
+        unsigned long long bytesReceived { 0 };
+    };
+
</ins><span class="cx"> private:
</span><span class="cx">     RTCStatsReport() = default;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCStatsReportidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl (214349 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl        2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -70,8 +70,6 @@
</span><span class="cx">     unsigned long long qpSum;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-// FIXME 169662: missing RTCCodecStats
-
</del><span class="cx"> [ JSGenerateToJSObject ]
</span><span class="cx"> dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
</span><span class="cx">     unsigned long packetsReceived;
</span><span class="lines">@@ -101,10 +99,44 @@
</span><span class="cx">     unsigned long framesEncoded;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+[ JSGenerateToJSObject ]
+dictionary RTCMediaStreamTrackStats : RTCStats {
+    DOMString trackIdentifier;
+    boolean remoteSource;
+    boolean ended;
+    boolean detached;
+    // FIXME: Add sequence&lt;DOMString&gt; ssrcIds;
+    unsigned long frameWidth;
+    unsigned long frameHeight;
+    double framesPerSecond;
+    unsigned long framesSent;
+    unsigned long framesReceived;
+    unsigned long framesDecoded;
+    unsigned long framesDropped;
+    unsigned long framesCorrupted;
+    unsigned long partialFramesLost;
+    unsigned long fullFramesLost;
+    double audioLevel;
+    double echoReturnLoss;
+    double echoReturnLossEnhancement;
+};
+
+[ JSGenerateToJSObject ]
+dictionary RTCDataChannelStats : RTCStats {
+    DOMString label;
+    DOMString protocol;
+    long datachannelid;
+    // FIXME: Switch state to RTCDataChannelState
+    DOMString state;
+    unsigned long messagesSent;
+    unsigned long long bytesSent;
+    unsigned long messagesReceived;
+    unsigned long long bytesReceived;
+};
+
+// FIXME 169662: missing RTCCodecStats
</ins><span class="cx"> // FIXME 169662: missing RTCPeerConnectionStats
</span><span class="cx"> // FIXME 169662: missing RTCMediaStreamStats
</span><del>-// FIXME 169662: missing RTCMediaStreamTrackStats
-// FIXME 169662: missing RTCDataChannelStats
</del><span class="cx"> // FIXME 169662: missing RTCTransportStats
</span><span class="cx"> // FIXME 169662: missing RTCIceCandidateStats
</span><span class="cx"> // FIXME 169662: missing RTCIceCandidatePairStats
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp (214349 => 214350)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp        2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp        2017-03-24 16:32:53 UTC (rev 214350)
</span><span class="lines">@@ -323,6 +323,65 @@
</span><span class="cx">         stats.framesEncoded = *rtcStats.frames_encoded;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline void fillRTCMediaStreamTrackStats(RTCStatsReport::MediaStreamTrackStats&amp; stats, const webrtc::RTCMediaStreamTrackStats&amp; rtcStats)
+{
+    fillRTCStats(stats, rtcStats);
+    if (rtcStats.track_identifier.is_defined())
+        stats.trackIdentifier = fromStdString(*rtcStats.track_identifier);
+    if (rtcStats.remote_source.is_defined())
+        stats.remoteSource = *rtcStats.remote_source;
+    if (rtcStats.ended.is_defined())
+        stats.ended = *rtcStats.ended;
+    if (rtcStats.detached.is_defined())
+        stats.detached = *rtcStats.detached;
+    if (rtcStats.frame_width.is_defined())
+        stats.frameWidth = *rtcStats.frame_width;
+    if (rtcStats.frame_height.is_defined())
+        stats.frameHeight = *rtcStats.frame_height;
+    if (rtcStats.frames_per_second.is_defined())
+        stats.framesPerSecond = *rtcStats.frames_per_second;
+    if (rtcStats.frames_sent.is_defined())
+        stats.framesSent = *rtcStats.frames_sent;
+    if (rtcStats.frames_received.is_defined())
+        stats.framesReceived = *rtcStats.frames_received;
+    if (rtcStats.frames_decoded.is_defined())
+        stats.framesDecoded = *rtcStats.frames_decoded;
+    if (rtcStats.frames_dropped.is_defined())
+        stats.framesDropped = *rtcStats.frames_dropped;
+    if (rtcStats.partial_frames_lost.is_defined())
+        stats.partialFramesLost = *rtcStats.partial_frames_lost;
+    if (rtcStats.full_frames_lost.is_defined())
+        stats.fullFramesLost = *rtcStats.full_frames_lost;
+    if (rtcStats.audio_level.is_defined())
+        stats.audioLevel = *rtcStats.audio_level;
+    if (rtcStats.echo_return_loss.is_defined())
+        stats.echoReturnLoss = *rtcStats.echo_return_loss;
+    if (rtcStats.echo_return_loss_enhancement.is_defined())
+        stats.echoReturnLossEnhancement = *rtcStats.echo_return_loss_enhancement;
+}
+
+static inline void fillRTCDataChannelStats(RTCStatsReport::DataChannelStats&amp; stats, const webrtc::RTCDataChannelStats&amp; rtcStats)
+{
+    fillRTCStats(stats, rtcStats);
+    
+    if (rtcStats.label.is_defined())
+        stats.label = fromStdString(*rtcStats.label);
+    if (rtcStats.protocol.is_defined())
+        stats.protocol = fromStdString(*rtcStats.protocol);
+    if (rtcStats.datachannelid.is_defined())
+        stats.datachannelid = *rtcStats.datachannelid;
+    if (rtcStats.state.is_defined())
+        stats.state = fromStdString(*rtcStats.state);
+    if (rtcStats.messages_sent.is_defined())
+        stats.messagesSent = *rtcStats.messages_sent;
+    if (rtcStats.bytes_sent.is_defined())
+        stats.bytesSent = *rtcStats.bytes_sent;
+    if (rtcStats.messages_received.is_defined())
+        stats.messagesReceived = *rtcStats.messages_received;
+    if (rtcStats.bytes_received.is_defined())
+        stats.bytesReceived = *rtcStats.bytes_received;
+}
+
</ins><span class="cx"> void LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered(const rtc::scoped_refptr&lt;const webrtc::RTCStatsReport&gt;&amp; rtcReport)
</span><span class="cx"> {
</span><span class="cx">     callOnMainThread([protectedThis = rtc::scoped_refptr&lt;LibWebRTCMediaEndpoint::StatsCollector&gt;(this), rtcReport] {
</span><span class="lines">@@ -338,13 +397,18 @@
</span><span class="cx">                 RTCStatsReport::InboundRTPStreamStats stats;
</span><span class="cx">                 fillInboundRTPStreamStats(stats, static_cast&lt;const webrtc::RTCInboundRTPStreamStats&amp;&gt;(rtcStats));
</span><span class="cx">                 report-&gt;addStats&lt;IDLDictionary&lt;RTCStatsReport::InboundRTPStreamStats&gt;&gt;(WTFMove(stats));
</span><del>-                return;
-            }
-            if (rtcStats.type() == webrtc::RTCOutboundRTPStreamStats::kType) {
</del><ins>+            } else if (rtcStats.type() == webrtc::RTCOutboundRTPStreamStats::kType) {
</ins><span class="cx">                 RTCStatsReport::OutboundRTPStreamStats stats;
</span><span class="cx">                 fillOutboundRTPStreamStats(stats, static_cast&lt;const webrtc::RTCOutboundRTPStreamStats&amp;&gt;(rtcStats));
</span><span class="cx">                 report-&gt;addStats&lt;IDLDictionary&lt;RTCStatsReport::OutboundRTPStreamStats&gt;&gt;(WTFMove(stats));
</span><del>-                return;
</del><ins>+            } else if (rtcStats.type() == webrtc::RTCMediaStreamTrackStats::kType) {
+                RTCStatsReport::MediaStreamTrackStats stats;
+                fillRTCMediaStreamTrackStats(stats, static_cast&lt;const webrtc::RTCMediaStreamTrackStats&amp;&gt;(rtcStats));
+                report-&gt;addStats&lt;IDLDictionary&lt;RTCStatsReport::MediaStreamTrackStats&gt;&gt;(WTFMove(stats));
+            } else if (rtcStats.type() == webrtc::RTCDataChannelStats::kType) {
+                RTCStatsReport::DataChannelStats stats;
+                fillRTCDataChannelStats(stats, static_cast&lt;const webrtc::RTCDataChannelStats&amp;&gt;(rtcStats));
+                report-&gt;addStats&lt;IDLDictionary&lt;RTCStatsReport::DataChannelStats&gt;&gt;(WTFMove(stats));
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     });
</span></span></pre>
</div>
</div>

</body>
</html>