summaryrefslogtreecommitdiffstats
path: root/content/browser/resources
diff options
context:
space:
mode:
authorjiayl@chromium.org <jiayl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-26 23:42:32 +0000
committerjiayl@chromium.org <jiayl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-26 23:42:32 +0000
commit2746df93f815c4d054f2197752879acd5b9327db (patch)
tree9881d97a056de6148ff1601d41dafe5428ac099b /content/browser/resources
parent1851802fee34e3f5b4a91770284ff960f09558e8 (diff)
downloadchromium_src-2746df93f815c4d054f2197752879acd5b9327db.zip
chromium_src-2746df93f815c4d054f2197752879acd5b9327db.tar.gz
chromium_src-2746df93f815c4d054f2197752879acd5b9327db.tar.bz2
Displays stream properties like msid/label with the ssrc for stats table and graphs. Adds the ability to expand/collapse a peerconnection section. Also adds more JS annotation and refactors the global functions into helper classes for better readability and maintainability.
BUG= Review URL: https://chromiumcodereview.appspot.com/13483014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196883 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/resources')
-rw-r--r--content/browser/resources/media/peer_connection_update_table.js128
-rw-r--r--content/browser/resources/media/ssrc_info_manager.js134
-rw-r--r--content/browser/resources/media/stats_graph_helper.js60
-rw-r--r--content/browser/resources/media/stats_table.js139
-rw-r--r--content/browser/resources/media/webrtc_internals.css41
-rw-r--r--content/browser/resources/media/webrtc_internals.js258
6 files changed, 559 insertions, 201 deletions
diff --git a/content/browser/resources/media/peer_connection_update_table.js b/content/browser/resources/media/peer_connection_update_table.js
new file mode 100644
index 0000000..facbefa
--- /dev/null
+++ b/content/browser/resources/media/peer_connection_update_table.js
@@ -0,0 +1,128 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * The data of a peer connection update.
+ * @param {number} pid The id of the renderer.
+ * @param {number} lid The id of the peer conneciton inside a renderer.
+ * @param {string} type The type of the update.
+ * @param {string} value The details of the update.
+ * @constructor
+ */
+var PeerConnectionUpdateEntry = function(pid, lid, type, value) {
+ /**
+ * @type {number}
+ */
+ this.pid = pid;
+
+ /**
+ * @type {number}
+ */
+ this.lid = lid;
+
+ /**
+ * @type {string}
+ */
+ this.type = type;
+
+ /**
+ * @type {string}
+ */
+ this.value = value;
+};
+
+
+/**
+ * Maintains the peer connection update log table.
+ */
+var PeerConnectionUpdateTable = (function() {
+ 'use strict';
+
+ /**
+ * @constructor
+ */
+ function PeerConnectionUpdateTable() {
+ /**
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.UPDATE_LOG_ID_SUFFIX_ = '-update-log';
+
+ /**
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.UPDATE_LOG_CONTAINER_CLASS_ = 'update-log-container';
+
+ /**
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.UPDATE_LOG_TABLE_CLASS_ = 'update-log-table';
+ }
+
+ PeerConnectionUpdateTable.prototype = {
+ /**
+ * Adds the update to the update table as a new row. The type of the update
+ * is set to the summary of the cell; clicking the cell will reveal or hide
+ * the details as the content of a TextArea element.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @param {!PeerConnectionUpdateEntry} update The update to add.
+ */
+ addPeerConnectionUpdate: function(peerConnectionElement, update) {
+ var tableElement = this.ensureUpdateContainer_(peerConnectionElement);
+
+ var row = document.createElement('tr');
+ tableElement.firstChild.appendChild(row);
+
+ row.innerHTML = '<td>' + (new Date()).toLocaleString() + '</td>';
+
+ if (update.value.length == 0) {
+ row.innerHTML += '<td>' + update.type + '</td>';
+ return;
+ }
+
+ row.innerHTML += '<td><details><summary>' + update.type +
+ '</summary></details></td>';
+
+ var valueContainer = document.createElement('pre');
+ var details = row.cells[1].childNodes[0];
+ details.appendChild(valueContainer);
+ valueContainer.textContent = update.value;
+ },
+
+ /**
+ * Makes sure the update log table of the peer connection is created.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @return {!Element} The log table element.
+ * @private
+ */
+ ensureUpdateContainer_: function(peerConnectionElement) {
+ var tableId = peerConnectionElement.id + this.UPDATE_LOG_ID_SUFFIX_;
+ var tableElement = $(tableId);
+ if (!tableElement) {
+ var tableContainer = document.createElement('div');
+ tableContainer.className = this.UPDATE_LOG_CONTAINER_CLASS_;
+ peerConnectionElement.appendChild(tableContainer);
+
+ tableElement = document.createElement('table');
+ tableElement.className = this.UPDATE_LOG_TABLE_CLASS_;
+ tableElement.id = tableId;
+ tableElement.border = 1;
+ tableContainer.appendChild(tableElement);
+ tableElement.innerHTML = '<tr><th>Time</th>' +
+ '<th class="update-log-header-event">Event</th></tr>';
+ }
+ return tableElement;
+ }
+ };
+
+ return PeerConnectionUpdateTable;
+})();
diff --git a/content/browser/resources/media/ssrc_info_manager.js b/content/browser/resources/media/ssrc_info_manager.js
new file mode 100644
index 0000000..8236e87
--- /dev/null
+++ b/content/browser/resources/media/ssrc_info_manager.js
@@ -0,0 +1,134 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * SsrcInfoManager stores the ssrc stream info extracted from SDP.
+ */
+var SsrcInfoManager = (function() {
+ 'use strict';
+
+ /**
+ * @constructor
+ */
+ function SsrcInfoManager() {
+ /**
+ * Map from ssrc id to an object containing all the stream properties.
+ * @type {!Object.<string, !Object.<string>>}
+ * @private
+ */
+ this.streamInfoContainer_ = {};
+
+ /**
+ * The string separating attibutes in an SDP.
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.ATTRIBUTE_SEPARATOR_ = /[\r,\n]/;
+
+ /**
+ * The regex separating fields within an ssrc description.
+ * @type {RegExp}
+ * @const
+ * @private
+ */
+ this.FIELD_SEPARATOR_REGEX_ = / .*:/;
+
+ /**
+ * The prefix string of an ssrc description.
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.SSRC_ATTRIBUTE_PREFIX_ = 'a=ssrc:';
+
+ /**
+ * The className of the ssrc info parent element.
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.SSRC_INFO_BLOCK_CLASS_ = 'ssrc-info-block';
+ }
+
+ SsrcInfoManager.prototype = {
+ /**
+ * Extracts the stream information from |sdp| and saves it.
+ * For example:
+ * a=ssrc:1234 msid:abcd
+ * a=ssrc:1234 label:hello
+ *
+ * @param {string} sdp The SDP string.
+ */
+ addSsrcStreamInfo: function(sdp) {
+ var attributes = sdp.split(this.ATTRIBUTE_SEPARATOR_);
+ for (var i = 0; i < attributes.length; ++i) {
+ // Check if this is a ssrc attribute.
+ if (attributes[i].indexOf(this.SSRC_ATTRIBUTE_PREFIX_) != 0)
+ continue;
+
+ var nextFieldIndex = attributes[i].search(this.FIELD_SEPARATOR_REGEX_);
+
+ if (nextFieldIndex == -1)
+ continue;
+
+ var ssrc = attributes[i].substring(this.SSRC_ATTRIBUTE_PREFIX_.length,
+ nextFieldIndex);
+ if (!this.streamInfoContainer_[ssrc])
+ this.streamInfoContainer_[ssrc] = {};
+
+ // Make |rest| starting at the next field.
+ var rest = attributes[i].substring(nextFieldIndex + 1);
+ var name, value;
+ while (rest.length > 0) {
+ nextFieldIndex = rest.search(this.FIELD_SEPARATOR_REGEX_);
+ if (nextFieldIndex == -1)
+ nextFieldIndex = rest.length;
+
+ // The field name is the string before the colon.
+ name = rest.substring(0, rest.indexOf(':'));
+ // The field value is from after the colon to the next field.
+ value = rest.substring(rest.indexOf(':') + 1, nextFieldIndex);
+ this.streamInfoContainer_[ssrc][name] = value;
+
+ // Move |rest| to the start of the next field.
+ rest = rest.substring(nextFieldIndex + 1);
+ }
+ }
+ },
+
+ /**
+ * @param {string} sdp The ssrc id.
+ * @return {!Object.<string>} The object containing the ssrc infomation.
+ */
+ getStreamInfo: function(ssrc) {
+ return this.streamInfoContainer_[ssrc];
+ },
+
+ /**
+ * Populate the ssrc information into |parentElement|, each field as a
+ * DIV element.
+ *
+ * @param {!Element} parentElement The parent element for the ssrc info.
+ * @param {string} ssrc The ssrc id.
+ */
+ populateSsrcInfo: function(parentElement, ssrc) {
+ if (!this.streamInfoContainer_[ssrc])
+ return;
+
+ parentElement.className = this.SSRC_INFO_BLOCK_CLASS_;
+
+ var fieldElement;
+ for (var property in this.streamInfoContainer_[ssrc]) {
+ fieldElement = document.createElement('div');
+ parentElement.appendChild(fieldElement);
+ fieldElement.textContent =
+ property + ':' + this.streamInfoContainer_[ssrc][property];
+ }
+ }
+ };
+
+ return SsrcInfoManager;
+})();
diff --git a/content/browser/resources/media/stats_graph_helper.js b/content/browser/resources/media/stats_graph_helper.js
index 2fe4114..c252f0a 100644
--- a/content/browser/resources/media/stats_graph_helper.js
+++ b/content/browser/resources/media/stats_graph_helper.js
@@ -14,6 +14,8 @@
<include src="data_series.js"/>
<include src="timeline_graph_view.js"/>
+var STATS_GRAPH_CONTAINER_HEADING_CLASS = 'stats-graph-container-heading';
+
// Specifies which stats should be drawn on the 'bweCompound' graph and how.
var bweCompoundGraphConfig = {
googAvailableSendBandwidth: {color: 'red'},
@@ -82,9 +84,12 @@ var dataSeries = {};
// Adds the stats report |singleReport| to the timeline graph for the given
// |peerConnectionElement| and |reportName|.
-function drawSingleReport(peerConnectionElement, reportName, singleReport) {
+function drawSingleReport(
+ peerConnectionElement, reportType, reportId, singleReport) {
if (!singleReport || !singleReport.values)
return;
+
+ var reportName = reportType + '-' + reportId;
for (var i = 0; i < singleReport.values.length - 1; i = i + 2) {
var rawLabel = singleReport.values[i];
var rawValue = parseInt(singleReport.values[i + 1]);
@@ -124,7 +129,7 @@ function drawSingleReport(peerConnectionElement, reportName, singleReport) {
if (!graphViews[graphViewId]) {
graphViews[graphViewId] = createStatsGraphView(peerConnectionElement,
- reportName,
+ reportType, reportId,
graphType);
var date = new Date(singleReport.timestamp);
graphViews[graphViewId].setDateRange(date, date);
@@ -150,41 +155,43 @@ function addDataSeriesPoint(dataSeriesId, time, label, value) {
dataSeries[dataSeriesId].addPoint(time, value);
}
-// Ensures a div container to hold all stats graphs for a report type
-// is created as a child of |peerConnectionElement|.
-function ensureStatsGraphTopContainer(peerConnectionElement, reportName) {
+// Ensures a div container to hold all stats graphs for one track is created as
+// a child of |peerConnectionElement|.
+function ensureStatsGraphTopContainer(
+ peerConnectionElement, reportType, reportId) {
var containerId = peerConnectionElement.id + '-' +
- reportName + '-graph-container';
+ reportType + '-' + reportId + '-graph-container';
var container = $(containerId);
if (!container) {
- container = document.createElement('div');
+ container = document.createElement('details');
container.id = containerId;
- container.className = 'stats-graph-container-collapsed';
+ container.className = 'stats-graph-container';
peerConnectionElement.appendChild(container);
- container.innerHTML =
- '<button>Expand/Collapse Graphs for ' + reportName + '</button>';
-
- // Expands or collapses the graphs on click.
- container.childNodes[0].addEventListener('click', function(event) {
- var element = event.target.parentNode;
- if (element.className == 'stats-graph-container-collapsed')
- element.className = 'stats-graph-container';
- else
- element.className = 'stats-graph-container-collapsed';
- });
+ container.innerHTML ='<summary><span></span></summary>';
+ container.firstChild.firstChild.className =
+ STATS_GRAPH_CONTAINER_HEADING_CLASS;
+ container.firstChild.firstChild.textContent =
+ 'Stats graphs for ' + reportType + '-' + reportId;
+
+ if (reportType == 'ssrc') {
+ var ssrcInfoElement = document.createElement('div');
+ container.firstChild.appendChild(ssrcInfoElement);
+ ssrcInfoManager.populateSsrcInfo(ssrcInfoElement, reportId);
+ }
}
return container;
}
// Creates the container elements holding a timeline graph
// and the TimelineGraphView object.
-function createStatsGraphView(peerConnectionElement, reportName, statsName) {
+function createStatsGraphView(
+ peerConnectionElement, reportType, reportId, statsName) {
var topContainer = ensureStatsGraphTopContainer(peerConnectionElement,
- reportName);
+ reportType, reportId);
- var graphViewId =
- peerConnectionElement.id + '-' + reportName + '-' + statsName;
+ var graphViewId = peerConnectionElement.id + '-' +
+ reportType + '-' + reportId + '-' + statsName;
var divId = graphViewId + '-div';
var canvasId = graphViewId + '-canvas';
var container = document.createElement("div");
@@ -194,9 +201,10 @@ function createStatsGraphView(peerConnectionElement, reportName, statsName) {
container.innerHTML = '<div>' + statsName + '</div>' +
'<div id=' + divId + '><canvas id=' + canvasId + '></canvas></div>';
if (statsName == 'bweCompound') {
- container.insertBefore(createBweCompoundLegend(peerConnectionElement,
- reportName),
- $(divId));
+ container.insertBefore(
+ createBweCompoundLegend(
+ peerConnectionElement, reportType + '-' + reportId),
+ $(divId));
}
return new TimelineGraphView(divId, canvasId);
}
diff --git a/content/browser/resources/media/stats_table.js b/content/browser/resources/media/stats_table.js
new file mode 100644
index 0000000..d31c73a
--- /dev/null
+++ b/content/browser/resources/media/stats_table.js
@@ -0,0 +1,139 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * Maintains the stats table.
+ * @param {SsrcInfoManager} ssrcInfoManager The source of the ssrc info.
+ */
+var StatsTable = (function(ssrcInfoManager) {
+ 'use strict';
+
+ /**
+ * @param {SsrcInfoManager} ssrcInfoManager The source of the ssrc info.
+ * @constructor
+ */
+ function StatsTable(ssrcInfoManager) {
+ /**
+ * @type {SsrcInfoManager}
+ * @private
+ */
+ this.ssrcInfoManager_ = ssrcInfoManager;
+ }
+
+ StatsTable.prototype = {
+ /**
+ * Adds |report| to the stats table of |peerConnectionElement|.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @param {!Object} report The object containing stats, which is the object
+ * containing timestamp and values, which is an array of strings, whose
+ * even index entry is the name of the stat, and the odd index entry is
+ * the value.
+ */
+ addStatsReport: function(peerConnectionElement, report) {
+ var statsTable = this.ensureStatsTable_(peerConnectionElement, report);
+
+ if (report.stats) {
+ this.addStatsToTable_(statsTable,
+ report.stats.timestamp, report.stats.values);
+ }
+ },
+
+ /**
+ * Ensure the DIV container for the stats tables is created as a child of
+ * |peerConnectionElement|.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @return {!Element} The stats table container.
+ * @private
+ */
+ ensureStatsTableContainer_: function(peerConnectionElement) {
+ var containerId = peerConnectionElement.id + '-table-container';
+ var container = $(containerId);
+ if (!container) {
+ container = document.createElement('div');
+ container.id = containerId;
+ container.className = 'stats-table-container';
+ peerConnectionElement.appendChild(container);
+ }
+ return container;
+ },
+
+ /**
+ * Ensure the stats table for track specified by |report| of PeerConnection
+ * |peerConnectionElement| is created.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @param {!Object} report The object containing stats, which is the object
+ * containing timestamp and values, which is an array of strings, whose
+ * even index entry is the name of the stat, and the odd index entry is
+ * the value.
+ * @return {!Element} The stats table element.
+ * @private
+ */
+ ensureStatsTable_: function(peerConnectionElement, report) {
+ var tableId = peerConnectionElement.id + '-table-' +
+ report.type + '-' + report.id;
+ var table = $(tableId);
+ if (!table) {
+ var container = this.ensureStatsTableContainer_(peerConnectionElement);
+ table = document.createElement('table');
+ container.appendChild(table);
+ table.id = tableId;
+ table.border = 1;
+
+ table.innerHTML = '<tr><th colspan=2></th></tr>';
+ table.rows[0].cells[0].textContent =
+ 'Statistics ' + report.type + '-' + report.id;
+ if (report.type == 'ssrc') {
+ table.insertRow(1);
+ table.rows[1].innerHTML = '<td colspan=2></td>';
+ this.ssrcInfoManager_.populateSsrcInfo(
+ table.rows[1].cells[0], report.id);
+ }
+ }
+ return table;
+ },
+
+ /**
+ * Update |statsTable| with |time| and |statsData|.
+ *
+ * @param {!Element} statsTable Which table to update.
+ * @param {number} time The number of miliseconds since epoch.
+ * @param {Array.<string>} statsData An array of stats name and value pairs.
+ * @private
+ */
+ addStatsToTable_: function(statsTable, time, statsData) {
+ var date = Date(time);
+ this.updateStatsTableRow_(statsTable, 'timestamp', date.toLocaleString());
+ for (var i = 0; i < statsData.length - 1; i = i + 2) {
+ this.updateStatsTableRow_(statsTable, statsData[i], statsData[i + 1]);
+ }
+ },
+
+ /**
+ * Update the value column of the stats row of |rowName| to |value|.
+ * A new row is created is this is the first report of this stats.
+ *
+ * @param {!Element} statsTable Which table to update.
+ * @param {string} rowName The name of the row to update.
+ * @param {string} value The new value to set.
+ * @private
+ */
+ updateStatsTableRow_: function(statsTable, rowName, value) {
+ var trId = statsTable.id + '-' + rowName;
+ var trElement = $(trId);
+ if (!trElement) {
+ trElement = document.createElement('tr');
+ trElement.id = trId;
+ statsTable.firstChild.appendChild(trElement);
+ trElement.innerHTML = '<td>' + rowName + '</td><td></td>';
+ }
+ trElement.cells[1].textContent = value;
+ }
+ };
+
+ return StatsTable;
+})();
diff --git a/content/browser/resources/media/webrtc_internals.css b/content/browser/resources/media/webrtc_internals.css
index 83d1f39..ebf07d5 100644
--- a/content/browser/resources/media/webrtc_internals.css
+++ b/content/browser/resources/media/webrtc_internals.css
@@ -2,25 +2,28 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-.log-container {
+
+.peer-connection-hidden > *:not(h3) {
+ display:none;
+}
+
+.update-log-container {
float: left;
}
-.stats-graph-container,
-.stats-graph-container-collapsed {
- clear: both;
- margin: 0.5em 0 0.5em 0;
+.ssrc-info-block {
+ color: #999;
+ font-size: 0.8em;
}
-.stats-graph-container button,
-.stats-graph-container-collapsed button {
- display: block;
- margin: 0;
- padding: 0;
+.stats-graph-container {
+ clear: both;
+ margin: 0.5em 0 0.5em 0;
}
-.stats-graph-container-collapsed .stats-graph-sub-container {
- display: none;
+.stats-graph-container-heading {
+ font-size: 0.8em;
+ font-weight: bold;
}
.stats-graph-sub-container {
@@ -47,7 +50,7 @@ body {
}
details {
- width: 30em;
+ min-width: 30em;
}
h3 + div {
@@ -64,9 +67,11 @@ h2 {
}
h3 {
- color: #666;
+ color: #555;
+ cursor: pointer;
font-size: 0.9em;
- margin: 1em 0 0.5em 0;
+ margin: 2em 0 0.5em 0;
+ text-decoration: underline;
}
li {
@@ -91,12 +96,6 @@ td:first-child {
padding-top: 0.3em;
}
-textarea {
- border: none;
- outline: none;
- width: 100%;
-}
-
table > tr {
vertical-align: top;
}
diff --git a/content/browser/resources/media/webrtc_internals.js b/content/browser/resources/media/webrtc_internals.js
index 1493d56d..05eb60ee 100644
--- a/content/browser/resources/media/webrtc_internals.js
+++ b/content/browser/resources/media/webrtc_internals.js
@@ -2,209 +2,159 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-<include src="stats_graph_helper.js"/>
var peerConnectionsListElem = null;
+var ssrcInfoManager = null;
+var peerConnectionUpdateTable = null;
+var statsTable = null;
+
+<include src="ssrc_info_manager.js"/>
+<include src="stats_graph_helper.js"/>
+<include src="stats_table.js"/>
+<include src="peer_connection_update_table.js"/>
function initialize() {
peerConnectionsListElem = $('peer-connections-list');
+ ssrcInfoManager = new SsrcInfoManager();
+ peerConnectionUpdateTable = new PeerConnectionUpdateTable();
+ statsTable = new StatsTable(ssrcInfoManager);
+
chrome.send('getAllUpdates');
- startGetStats();
-}
-// Polls stats from all PeerConnections every second.
-function startGetStats() {
- if (document.getElementsByTagName('li').length)
- chrome.send('getAllStats');
- window.setTimeout(startGetStats, 1000);
+ // Requests stats from all peer connections every second.
+ window.setInterval(function() {
+ if (peerConnectionsListElem.getElementsByTagName('li').length > 0)
+ chrome.send('getAllStats');
+ }, 1000);
}
+document.addEventListener('DOMContentLoaded', initialize);
+
+/**
+ * A helper function for getting a peer connection element id.
+ *
+ * @param {!Object.<string, number>} data The object containing the pid and lid
+ * of the peer connection.
+ * @return {string} The peer connection element id.
+ */
function getPeerConnectionId(data) {
return data.pid + '-' + data.lid;
}
-// Makes sure a LI element representing a PeerConnection is created
-// and appended to peerConnectionListElem.
-function ensurePeerConnectionElement(id) {
- var element = $(id);
- if (!element) {
- element = document.createElement('li');
- peerConnectionsListElem.appendChild(element);
- element.id = id;
- }
- return element;
-}
-
-// Makes sure the table representing the PeerConnection event log is created
-// and appended to peerConnectionElement.
-function ensurePeerConnectionLog(peerConnectionElement) {
- var logId = peerConnectionElement.id + '-log';
- var logElement = $(logId);
- if (!logElement) {
- var container = document.createElement('div');
- container.className = 'log-container';
- peerConnectionElement.appendChild(container);
-
- logElement = document.createElement('table');
- logElement.id = logId;
- logElement.className = 'log-table';
- logElement.border = 1;
- container.appendChild(logElement);
- logElement.innerHTML = '<tr><th>Time</th>' +
- '<th class="log-header-event">Event</th></tr>';
- }
- return logElement;
-}
-
-// Add the update to the log table as a new row. The type of the update is set
-// as the text of the cell; clicking the cell will reveal or hide the details
-// as the content of a TextArea element.
-function addToPeerConnectionLog(logElement, update) {
- var row = document.createElement('tr');
- logElement.appendChild(row);
-
- var expandable = (update.value.length > 0);
- // details.open is true initially so that we can get the real scrollHeight
- // of the textareas.
- row.innerHTML =
- '<td>' + (new Date()).toLocaleString() + '</td>' +
- (expandable ?
- '<td><details open><summary>' + update.type + '</summary>' +
- '</details></td>' :
- '<td>' + update.type + '</td>');
- if (!expandable)
- return;
-
- var valueContainer = document.createElement('textarea');
- var details = row.cells[1].childNodes[0];
- details.appendChild(valueContainer);
- valueContainer.value = update.value;
- valueContainer.style.height = valueContainer.scrollHeight + 'px';
- details.open = false;
-}
-
-// Ensure the DIV container for the stats tables is created as a child of
-// |peerConnectionElement|.
-function ensureStatsTableContainer(peerConnectionElement) {
- var containerId = peerConnectionElement.id + '-table-container';
- var container = $(containerId);
- if (!container) {
- container = document.createElement('div');
- container.id = containerId;
- container.className = 'stats-table-container';
- peerConnectionElement.appendChild(container);
- }
- return container;
-}
-
-// Ensure the stats table for track |statsId| of PeerConnection
-// |peerConnectionElement| is created as a child of the stats table container.
-function ensureStatsTable(peerConnectionElement, statsId) {
- var tableId = peerConnectionElement.id + '-table-' + statsId;
- var table = $(tableId);
- if (!table) {
- var container = ensureStatsTableContainer(peerConnectionElement);
- table = document.createElement('table');
- container.appendChild(table);
- table.id = tableId;
- table.border = 1;
- table.innerHTML = '<th>Statistics ' + statsId + '</th>';
- }
- return table;
-}
-// Update the value column of the stats row of |rowName| to |value|.
-// A new row is created is this is the first report of this stats.
-function updateStatsTableRow(statsTable, rowName, value) {
- var trId = statsTable.id + '-' + rowName;
- var trElement = $(trId);
- if (!trElement) {
- trElement = document.createElement('tr');
- trElement.id = trId;
- statsTable.appendChild(trElement);
- trElement.innerHTML = '<td>' + rowName + '</td><td></td>';
+/**
+ * Extracts ssrc info from a setLocal/setRemoteDescription update.
+ *
+ * @param {!PeerConnectionUpdateEntry} data The peer connection update data.
+ */
+function extractSsrcInfo(data) {
+ if (data.type == 'setLocalDescription' ||
+ data.type == 'setRemoteDescription') {
+ ssrcInfoManager.addSsrcStreamInfo(data.value);
}
- trElement.cells[1].textContent = value;
}
-// Add |singleReport| to the stats table.
-function addSingleReportToTable(statsTable, singleReport) {
- if (!singleReport || !singleReport.values || singleReport.values.length == 0)
- return;
- var date = Date(singleReport.timestamp);
- updateStatsTableRow(statsTable, 'timestamp', date.toLocaleString());
- for (var i = 0; i < singleReport.values.length - 1; i = i + 2) {
- updateStatsTableRow(statsTable, singleReport.values[i],
- singleReport.values[i + 1]);
- }
-}
+/**
+ * Browser message handlers.
+ */
-//
-// Browser message handlers.
-//
-// data = {pid:|integer|, lid:|integer|}.
+/**
+ * Removes all information about a peer connection.
+ *
+ * @param {!Object.<string, number>} data The object containing the pid and lid
+ * of a peer connection.
+ */
function removePeerConnection(data) {
var element = $(getPeerConnectionId(data));
if (element)
peerConnectionsListElem.removeChild(element);
}
-// data = {pid:|integer|, lid:|integer|,
-// url:|string|, servers:|string|, constraints:|string|}.
+
+/**
+ * Adds a peer connection.
+ *
+ * @param {!Object} data The object containing the pid, lid, url, servers, and
+ * constraints of a peer connection.
+ */
function addPeerConnection(data) {
- var peerConnectionElement = ensurePeerConnectionElement(
- getPeerConnectionId(data));
+ var peerConnectionElement = $(getPeerConnectionId(data));
+ if (!peerConnectionElement) {
+ peerConnectionElement = document.createElement('li');
+ peerConnectionsListElem.appendChild(peerConnectionElement);
+ peerConnectionElement.id = getPeerConnectionId(data);
+ }
peerConnectionElement.innerHTML =
'<h3>PeerConnection ' + peerConnectionElement.id + '</h3>' +
'<div>' + data.url + ' ' + data.servers + ' ' + data.constraints +
'</div>';
+
+ // Clicking the heading can expand or collapse the peer connection item.
+ peerConnectionElement.firstChild.title = 'Click to collapse or expand';
+ peerConnectionElement.firstChild.addEventListener('click', function(e) {
+ if (e.target.parentElement.className == '')
+ e.target.parentElement.className = 'peer-connection-hidden';
+ else
+ e.target.parentElement.className = '';
+ });
return peerConnectionElement;
}
-// data = {pid:|integer|, lid:|integer|, type:|string|, value:|string|}.
+
+/**
+ * Adds a peer connection update.
+ *
+ * @param {!PeerConnectionUpdateEntry} data The peer connection update data.
+ */
function updatePeerConnection(data) {
- var peerConnectionElement = ensurePeerConnectionElement(
- getPeerConnectionId(data));
- var logElement = ensurePeerConnectionLog(peerConnectionElement);
- addToPeerConnectionLog(logElement, data);
+ var peerConnectionElement = $(getPeerConnectionId(data));
+ peerConnectionUpdateTable.addPeerConnectionUpdate(
+ peerConnectionElement, data);
+ extractSsrcInfo(data);
}
-// data is an array and each entry is
-// {pid:|integer|, lid:|integer|,
-// url:|string|, servers:|string|, constraints:|string|, log:|array|},
-// each entry of log is {type:|string|, value:|string|}.
+
+/**
+ * Adds the information of all peer connections created so far.
+ *
+ * @param {Array.<!Object>} data An array of the information of all peer
+ * connections. Each array item contains pid, lid, url, servers,
+ * constraints, and an array of updates as the log.
+ */
function updateAllPeerConnections(data) {
for (var i = 0; i < data.length; ++i) {
var peerConnection = addPeerConnection(data[i]);
- var logElement = ensurePeerConnectionLog(peerConnection);
var log = data[i].log;
for (var j = 0; j < log.length; ++j) {
- addToPeerConnectionLog(logElement, log[j]);
+ peerConnectionUpdateTable.addPeerConnectionUpdate(
+ peerConnection, log[j]);
+ extractSsrcInfo(log[j]);
}
}
}
-// data = {pid:|integer|, lid:|integer|, reports:|array|}.
-// Each entry of reports =
-// {id:|string|, type:|string|, stats:|object|},
-// where |stats| = {timestamp: |double|, values: |array|},
-// where |values| is an array of strings, whose even index entry represents
-// the name of the stat, and the odd index entry represents the value of
-// the stat.
+
+/**
+ * Handles the report of stats.
+ *
+ * @param {!Object} data The object containing pid, lid, and reports, where
+ * reports is an array of stats reports. Each report contains id, type,
+ * and stats, where stats is the object containing timestamp and values,
+ * which is an array of strings, whose even index entry is the name of the
+ * stat, and the odd index entry is the value.
+ */
function addStats(data) {
- var peerConnectionElement = ensurePeerConnectionElement(
- getPeerConnectionId(data));
+ var peerConnectionElement = $(getPeerConnectionId(data));
+ if (!peerConnectionElement)
+ return;
+
for (var i = 0; i < data.reports.length; ++i) {
var report = data.reports[i];
- var reportName = report.type + '-' + report.id;
- var statsTable = ensureStatsTable(peerConnectionElement, reportName);
-
- addSingleReportToTable(statsTable, report.stats);
- drawSingleReport(peerConnectionElement, reportName, report.stats);
+ statsTable.addStatsReport(peerConnectionElement, report);
+ drawSingleReport(peerConnectionElement,
+ report.type, report.id, report.stats);
}
}
-
-document.addEventListener('DOMContentLoaded', initialize);