summaryrefslogtreecommitdiff
path: root/chromium/content/browser/resources/media/peer_connection_update_table.js
blob: 09998a6bf7dfd1f5ac65b94a57325193986d1dd5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// 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);

      var time = new Date(parseFloat(update.time));
      row.innerHTML = '<td>' + time.toLocaleString() + '</td>';

      // map internal event names to spec event names.
      var type = {
        onRenegotiationNeeded: 'negotiationneeded',
        signalingStateChange: 'signalingstatechange',
        iceGatheringStateChange: 'icegatheringstatechange',
        iceConnectionStateChange: 'iceconnectionstatechange',
        onIceCandidate: 'icecandidate',
        stop: 'close'
      }[update.type] || update.type;

      if (update.value.length == 0) {
        row.innerHTML += '<td>' + type + '</td>';
        return;
      }

      if (update.type === 'onIceCandidate' ||
          update.type === 'addIceCandidate') {
        // extract ICE candidate type from the field following typ.
        var candidateType = update.value.match(
          /(?: typ )(host|srflx|relay)/);
        if (candidateType) {
          type += ' (' + candidateType[1] + ')';
        }
      }
      row.innerHTML += '<td><details><summary>' + type +
          '</summary></details></td>';

      var valueContainer = document.createElement('pre');
      var details = row.cells[1].childNodes[0];
      details.appendChild(valueContainer);

      // Highlight ICE failures and failure callbacks.
      if ((update.type === 'iceConnectionStateChange' &&
           update.value === 'ICEConnectionStateFailed') ||
          update.type.indexOf('OnFailure') !== -1 ||
          update.type === 'addIceCandidateFailed') {
        valueContainer.parentElement.classList.add('update-log-failure');
      }
      // Highlight legacy streams API usage.
      if (update.type === 'addStream' || update.type === 'removeStream') {
        valueContainer.parentElement.classList.add(
            'update-log-legacy-api-usage');
        valueContainer.parentElement.title = update.type + ' is no longer ' +
            'part of the WebRTC API and may be removed in future versions. ' +
            'Use the addTrack/removeTrack APIs instead.';
      }

      var value = update.value;
      // map internal names and values to names and events from the
      // specification. This is a display change which shall not
      // change the JSON dump.
      if (update.type === 'iceConnectionStateChange') {
        value = {
          ICEConnectionStateNew: 'new',
          ICEConnectionStateChecking: 'checking',
          ICEConnectionStateConnected: 'connected',
          ICEConnectionStateCompleted: 'completed',
          ICEConnectionStateFailed: 'failed',
          ICEConnectionStateDisconnected: 'disconnected',
          ICEConnectionStateClosed: 'closed',
        }[value] || value;
      } else if (update.type === 'iceGatheringStateChange') {
        value = {
          ICEGatheringStateNew: 'new',
          ICEGatheringStateGathering: 'gathering',
          ICEGatheringStateComplete: 'complete',
        }[value] || value;
      } else if (update.type === 'signalingStateChange') {
        value = {
          SignalingStateStable: 'stable',
          SignalingStateHaveLocalOffer: 'have-local-offer',
          SignalingStateHaveRemoteOffer: 'have-remote-offer',
          SignalingStateHaveLocalPrAnswer: 'have-local-pranswer',
          SignalingStateHaveRemotePrAnswer: 'have-remote-pranswer',
          SignalingStateClosed: 'closed',
        }[value] || value;
      }

      valueContainer.textContent = 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;
})();