1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5var tabView = null; 6var ssrcInfoManager = null; 7var peerConnectionUpdateTable = null; 8var statsTable = null; 9var dumpCreator = null; 10/** A map from peer connection id to the PeerConnectionRecord. */ 11var peerConnectionDataStore = {}; 12 13/** A simple class to store the updates and stats data for a peer connection. */ 14var PeerConnectionRecord = (function() { 15 /** @constructor */ 16 function PeerConnectionRecord() { 17 /** @private */ 18 this.record_ = { 19 constraints: {}, 20 servers: [], 21 stats: {}, 22 updateLog: [], 23 url: '', 24 }; 25 }; 26 27 PeerConnectionRecord.prototype = { 28 /** @override */ 29 toJSON: function() { 30 return this.record_; 31 }, 32 33 /** 34 * Adds the initilization info of the peer connection. 35 * @param {string} url The URL of the web page owning the peer connection. 36 * @param {Array} servers STUN servers used by the peer connection. 37 * @param {!Object} constraints Media constraints. 38 */ 39 initialize: function(url, servers, constraints) { 40 this.record_.url = url; 41 this.record_.servers = servers; 42 this.record_.constraints = constraints; 43 }, 44 45 /** 46 * @param {string} dataSeriesId The TimelineDataSeries identifier. 47 * @return {!TimelineDataSeries} 48 */ 49 getDataSeries: function(dataSeriesId) { 50 return this.record_.stats[dataSeriesId]; 51 }, 52 53 /** 54 * @param {string} dataSeriesId The TimelineDataSeries identifier. 55 * @param {!TimelineDataSeries} dataSeries The TimelineDataSeries to set to. 56 */ 57 setDataSeries: function(dataSeriesId, dataSeries) { 58 this.record_.stats[dataSeriesId] = dataSeries; 59 }, 60 61 /** 62 * @param {string} type The type of the update. 63 * @param {string} value The value of the update. 64 */ 65 addUpdate: function(type, value) { 66 this.record_.updateLog.push({ 67 time: (new Date()).toLocaleString(), 68 type: type, 69 value: value, 70 }); 71 }, 72 }; 73 74 return PeerConnectionRecord; 75})(); 76 77// The maximum number of data points bufferred for each stats. Old data points 78// will be shifted out when the buffer is full. 79var MAX_STATS_DATA_POINT_BUFFER_SIZE = 1000; 80 81<include src="tab_view.js"/> 82<include src="data_series.js"/> 83<include src="ssrc_info_manager.js"/> 84<include src="stats_graph_helper.js"/> 85<include src="stats_table.js"/> 86<include src="peer_connection_update_table.js"/> 87<include src="dump_creator.js"/> 88 89 90function initialize() { 91 dumpCreator = new DumpCreator($('content-root')); 92 tabView = new TabView($('content-root')); 93 ssrcInfoManager = new SsrcInfoManager(); 94 peerConnectionUpdateTable = new PeerConnectionUpdateTable(); 95 statsTable = new StatsTable(ssrcInfoManager); 96 97 chrome.send('getAllUpdates'); 98 99 // Requests stats from all peer connections every second. 100 window.setInterval(function() { 101 if (Object.keys(peerConnectionDataStore).length > 0) 102 chrome.send('getAllStats'); 103 }, 1000); 104} 105document.addEventListener('DOMContentLoaded', initialize); 106 107 108/** 109 * A helper function for getting a peer connection element id. 110 * 111 * @param {!Object.<string, number>} data The object containing the pid and lid 112 * of the peer connection. 113 * @return {string} The peer connection element id. 114 */ 115function getPeerConnectionId(data) { 116 return data.pid + '-' + data.lid; 117} 118 119 120/** 121 * Extracts ssrc info from a setLocal/setRemoteDescription update. 122 * 123 * @param {!PeerConnectionUpdateEntry} data The peer connection update data. 124 */ 125function extractSsrcInfo(data) { 126 if (data.type == 'setLocalDescription' || 127 data.type == 'setRemoteDescription') { 128 ssrcInfoManager.addSsrcStreamInfo(data.value); 129 } 130} 131 132 133/** 134 * Helper for adding a peer connection update. 135 * 136 * @param {Element} peerConnectionElement 137 * @param {!PeerConnectionUpdateEntry} update The peer connection update data. 138 */ 139function addPeerConnectionUpdate(peerConnectionElement, update) { 140 peerConnectionUpdateTable.addPeerConnectionUpdate(peerConnectionElement, 141 update); 142 extractSsrcInfo(update); 143 peerConnectionDataStore[peerConnectionElement.id].addUpdate( 144 update.type, update.value); 145} 146 147 148/** Browser message handlers. */ 149 150 151/** 152 * Removes all information about a peer connection. 153 * 154 * @param {!Object.<string, number>} data The object containing the pid and lid 155 * of a peer connection. 156 */ 157function removePeerConnection(data) { 158 var element = $(getPeerConnectionId(data)); 159 if (element) { 160 delete peerConnectionDataStore[element.id]; 161 tabView.removeTab(element.id); 162 } 163} 164 165 166/** 167 * Adds a peer connection. 168 * 169 * @param {!Object} data The object containing the pid, lid, url, servers, and 170 * constraints of a peer connection. 171 */ 172function addPeerConnection(data) { 173 var id = getPeerConnectionId(data); 174 175 if (!peerConnectionDataStore[id]) { 176 peerConnectionDataStore[id] = new PeerConnectionRecord(); 177 } 178 peerConnectionDataStore[id].initialize( 179 data.url, data.servers, data.constraints); 180 181 var peerConnectionElement = $(id); 182 if (!peerConnectionElement) { 183 peerConnectionElement = tabView.addTab(id, data.url); 184 } 185 peerConnectionElement.innerHTML = 186 '<p>' + data.url + ' ' + data.servers + ' ' + data.constraints + 187 '</p>'; 188 189 return peerConnectionElement; 190} 191 192 193/** 194 * Adds a peer connection update. 195 * 196 * @param {!PeerConnectionUpdateEntry} data The peer connection update data. 197 */ 198function updatePeerConnection(data) { 199 var peerConnectionElement = $(getPeerConnectionId(data)); 200 addPeerConnectionUpdate(peerConnectionElement, data); 201} 202 203 204/** 205 * Adds the information of all peer connections created so far. 206 * 207 * @param {Array.<!Object>} data An array of the information of all peer 208 * connections. Each array item contains pid, lid, url, servers, 209 * constraints, and an array of updates as the log. 210 */ 211function updateAllPeerConnections(data) { 212 for (var i = 0; i < data.length; ++i) { 213 var peerConnection = addPeerConnection(data[i]); 214 215 var log = data[i].log; 216 if (!log) 217 continue; 218 for (var j = 0; j < log.length; ++j) { 219 addPeerConnectionUpdate(peerConnection, log[j]); 220 } 221 } 222} 223 224 225/** 226 * Handles the report of stats. 227 * 228 * @param {!Object} data The object containing pid, lid, and reports, where 229 * reports is an array of stats reports. Each report contains id, type, 230 * and stats, where stats is the object containing timestamp and values, 231 * which is an array of strings, whose even index entry is the name of the 232 * stat, and the odd index entry is the value. 233 */ 234function addStats(data) { 235 var peerConnectionElement = $(getPeerConnectionId(data)); 236 if (!peerConnectionElement) 237 return; 238 239 for (var i = 0; i < data.reports.length; ++i) { 240 var report = data.reports[i]; 241 statsTable.addStatsReport(peerConnectionElement, report); 242 drawSingleReport(peerConnectionElement, report); 243 } 244} 245 246 247/** 248 * Delegates to dumpCreator to update the recording status. 249 * @param {!Object.<string>} update Key-value pairs describing the status of the 250 * RTP recording. 251 */ 252function updateDumpStatus(update) { 253 dumpCreator.onUpdate(update); 254} 255