• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/** A list of getUserMedia requests. */
13var userMediaRequests = [];
14
15/** A simple class to store the updates and stats data for a peer connection. */
16var PeerConnectionRecord = (function() {
17  /** @constructor */
18  function PeerConnectionRecord() {
19    /** @private */
20    this.record_ = {
21      constraints: {},
22      servers: [],
23      stats: {},
24      updateLog: [],
25      url: '',
26    };
27  };
28
29  PeerConnectionRecord.prototype = {
30    /** @override */
31    toJSON: function() {
32      return this.record_;
33    },
34
35    /**
36     * Adds the initilization info of the peer connection.
37     * @param {string} url The URL of the web page owning the peer connection.
38     * @param {Array} servers STUN servers used by the peer connection.
39     * @param {!Object} constraints Media constraints.
40     */
41    initialize: function(url, servers, constraints) {
42      this.record_.url = url;
43      this.record_.servers = servers;
44      this.record_.constraints = constraints;
45    },
46
47    /**
48     * @param {string} dataSeriesId The TimelineDataSeries identifier.
49     * @return {!TimelineDataSeries}
50     */
51    getDataSeries: function(dataSeriesId) {
52      return this.record_.stats[dataSeriesId];
53    },
54
55    /**
56     * @param {string} dataSeriesId The TimelineDataSeries identifier.
57     * @param {!TimelineDataSeries} dataSeries The TimelineDataSeries to set to.
58     */
59    setDataSeries: function(dataSeriesId, dataSeries) {
60      this.record_.stats[dataSeriesId] = dataSeries;
61    },
62
63    /**
64     * @param {string} type The type of the update.
65     * @param {string} value The value of the update.
66     */
67    addUpdate: function(type, value) {
68      this.record_.updateLog.push({
69        time: (new Date()).toLocaleString(),
70        type: type,
71        value: value,
72      });
73    },
74  };
75
76  return PeerConnectionRecord;
77})();
78
79// The maximum number of data points bufferred for each stats. Old data points
80// will be shifted out when the buffer is full.
81var MAX_STATS_DATA_POINT_BUFFER_SIZE = 1000;
82
83<include src="tab_view.js"/>
84<include src="data_series.js"/>
85<include src="ssrc_info_manager.js"/>
86<include src="stats_graph_helper.js"/>
87<include src="stats_table.js"/>
88<include src="peer_connection_update_table.js"/>
89<include src="dump_creator.js"/>
90
91
92function initialize() {
93  dumpCreator = new DumpCreator($('content-root'));
94  tabView = new TabView($('content-root'));
95  ssrcInfoManager = new SsrcInfoManager();
96  peerConnectionUpdateTable = new PeerConnectionUpdateTable();
97  statsTable = new StatsTable(ssrcInfoManager);
98
99  chrome.send('finishedDOMLoad');
100
101  // Requests stats from all peer connections every second.
102  window.setInterval(requestStats, 1000);
103}
104document.addEventListener('DOMContentLoaded', initialize);
105
106
107/** Sends a request to the browser to get peer connection statistics. */
108function requestStats() {
109  if (Object.keys(peerConnectionDataStore).length > 0)
110    chrome.send('getAllStats');
111}
112
113
114/**
115 * A helper function for getting a peer connection element id.
116 *
117 * @param {!Object.<string, number>} data The object containing the pid and lid
118 *     of the peer connection.
119 * @return {string} The peer connection element id.
120 */
121function getPeerConnectionId(data) {
122  return data.pid + '-' + data.lid;
123}
124
125
126/**
127 * Extracts ssrc info from a setLocal/setRemoteDescription update.
128 *
129 * @param {!PeerConnectionUpdateEntry} data The peer connection update data.
130 */
131function extractSsrcInfo(data) {
132  if (data.type == 'setLocalDescription' ||
133      data.type == 'setRemoteDescription') {
134    ssrcInfoManager.addSsrcStreamInfo(data.value);
135  }
136}
137
138
139/**
140 * Helper for adding a peer connection update.
141 *
142 * @param {Element} peerConnectionElement
143 * @param {!PeerConnectionUpdateEntry} update The peer connection update data.
144 */
145function addPeerConnectionUpdate(peerConnectionElement, update) {
146  peerConnectionUpdateTable.addPeerConnectionUpdate(peerConnectionElement,
147                                                    update);
148  extractSsrcInfo(update);
149  peerConnectionDataStore[peerConnectionElement.id].addUpdate(
150      update.type, update.value);
151}
152
153
154/** Browser message handlers. */
155
156
157/**
158 * Removes all information about a peer connection.
159 *
160 * @param {!Object.<string, number>} data The object containing the pid and lid
161 *     of a peer connection.
162 */
163function removePeerConnection(data) {
164  var element = $(getPeerConnectionId(data));
165  if (element) {
166    delete peerConnectionDataStore[element.id];
167    tabView.removeTab(element.id);
168  }
169}
170
171
172/**
173 * Adds a peer connection.
174 *
175 * @param {!Object} data The object containing the pid, lid, url, servers, and
176 *     constraints of a peer connection.
177 */
178function addPeerConnection(data) {
179  var id = getPeerConnectionId(data);
180
181  if (!peerConnectionDataStore[id]) {
182    peerConnectionDataStore[id] = new PeerConnectionRecord();
183  }
184  peerConnectionDataStore[id].initialize(
185      data.url, data.servers, data.constraints);
186
187  var peerConnectionElement = $(id);
188  if (!peerConnectionElement) {
189    peerConnectionElement = tabView.addTab(id, data.url);
190  }
191  peerConnectionElement.innerHTML =
192      '<p>' + data.url + ' ' + data.servers + ' ' + data.constraints +
193      '</p>';
194
195  return peerConnectionElement;
196}
197
198
199/**
200 * Adds a peer connection update.
201 *
202 * @param {!PeerConnectionUpdateEntry} data The peer connection update data.
203 */
204function updatePeerConnection(data) {
205  var peerConnectionElement = $(getPeerConnectionId(data));
206  addPeerConnectionUpdate(peerConnectionElement, data);
207}
208
209
210/**
211 * Adds the information of all peer connections created so far.
212 *
213 * @param {Array.<!Object>} data An array of the information of all peer
214 *     connections. Each array item contains pid, lid, url, servers,
215 *     constraints, and an array of updates as the log.
216 */
217function updateAllPeerConnections(data) {
218  for (var i = 0; i < data.length; ++i) {
219    var peerConnection = addPeerConnection(data[i]);
220
221    var log = data[i].log;
222    if (!log)
223      continue;
224    for (var j = 0; j < log.length; ++j) {
225      addPeerConnectionUpdate(peerConnection, log[j]);
226    }
227  }
228  requestStats();
229}
230
231
232/**
233 * Handles the report of stats.
234 *
235 * @param {!Object} data The object containing pid, lid, and reports, where
236 *     reports is an array of stats reports. Each report contains id, type,
237 *     and stats, where stats is the object containing timestamp and values,
238 *     which is an array of strings, whose even index entry is the name of the
239 *     stat, and the odd index entry is the value.
240 */
241function addStats(data) {
242  var peerConnectionElement = $(getPeerConnectionId(data));
243  if (!peerConnectionElement)
244    return;
245
246  for (var i = 0; i < data.reports.length; ++i) {
247    var report = data.reports[i];
248    statsTable.addStatsReport(peerConnectionElement, report);
249    drawSingleReport(peerConnectionElement, report);
250  }
251}
252
253
254/**
255 * Adds a getUserMedia request.
256 *
257 * @param {!Object} data The object containing rid {number}, pid {number},
258 *     origin {string}, audio {string}, video {string}.
259 */
260function addGetUserMedia(data) {
261  // TODO(jiayl): add the getUserMedia info to the tabbed UI.
262  userMediaRequests.push(data);
263}
264
265
266/**
267 * Removes the getUserMedia requests from the specified |rid|.
268 *
269 * @param {!Object} data The object containing rid {number}, the render id.
270 */
271function removeGetUserMediaForRenderer(data) {
272  // TODO(jiayl): remove the getUserMedia info from the tabbed UI.
273  for (var i = userMediaRequests.length - 1; i >= 0; --i) {
274    if (userMediaRequests[i].rid == data.rid)
275      userMediaRequests.splice(i, 1);
276  }
277}
278
279
280/**
281 * Notification that the AEC recording file selection dialog was cancelled,
282 * i.e. AEC has not been enabled.
283 */
284function aecRecordingFileSelectionCancelled() {
285  dumpCreator.disableAecRecording();
286}
287
288
289/**
290 * Set
291 */
292function enableAecRecording() {
293  dumpCreator.enableAecRecording();
294}
295