summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/chromeos/network.js
blob: 4cfec580b80542ec461d2848a8ef8b3d71ee7127 (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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
// Copyright 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.

var NetworkUI = function() {
  // Properties to display in the network state table. Each entry can be either
  // a single state field or an array of state fields. If more than one is
  // specified then the first non empty value is used.
  var NETWORK_STATE_FIELDS = [
    'Name', 'Type', 'State', 'Profile', 'Connectable',
    'Error', 'Address', 'Security',
    ['Cellular.NetworkTechnology', 'EAP.EAP'],
    'Cellular.ActivationState', 'Cellular.RoamingState',
    'Cellular.OutOfCredits', 'Strength'
  ];

  var FAVORITE_STATE_FIELDS = [
    'Name', 'Type', 'Profile', 'onc_source'
  ];

  var LOG_LEVEL_CLASSNAME = {
    'Error': 'network-log-level-error',
    'User': 'network-log-level-user',
    'Event': 'network-log-level-event',
    'Debug': 'network-log-level-debug'
  };

  var LOG_LEVEL_CHECKBOX = {
    'Error': 'log-error',
    'User': 'log-user',
    'Event': 'log-event',
    'Debug': 'log-debug'
  };

  /**
   * Create a tag of log level.
   *
   * @param {string} level A string that represents log level.
   * @return {DOMElement} The created span element.
   */
  var createLevelTag = function(level) {
    var tag = document.createElement('span');
    tag.className = 'network-level-tag';
    tag.textContent = level;
    tag.classList.add(LOG_LEVEL_CLASSNAME[level]);
    return tag;
  };

  /**
   * Creates an element that contains the time, the event, the level and
   * the description of the given log entry.
   *
   * @param {Object} logEntry An object that represents a single line of log.
   * @return {DOMElement}  The created p element that represents the log entry.
   */
  var createLogEntryText = function(logEntry) {
    var level = logEntry['level'];
    if (!$(LOG_LEVEL_CHECKBOX[level]).checked)
      return null;
    var res = document.createElement('p');
    var textWrapper = document.createElement('span');
    var fileinfo = '';
    if ($('log-fileinfo').checked)
      fileinfo = logEntry['file'];
    var timestamp = '';
    if ($('log-timedetail').checked)
      timestamp = logEntry['timestamp'];
    else
      timestamp = logEntry['timestampshort'];
    textWrapper.textContent = loadTimeData.getStringF(
      'logEntryFormat',
      timestamp,
      fileinfo,
      logEntry['event'],
      logEntry['description']);
    res.appendChild(createLevelTag(level));
    res.appendChild(textWrapper);
    return res;
  };

  /**
   * Create event log entries.
   *
   * @param {Array.<string>} logEntries A array of strings that each string
   *     represents a log event in JSON format.
   */
  var createEventLog = function(logEntries) {
    var container = $('network-log-container');
    container.textContent = '';
    for (var i = 0; i < logEntries.length; ++i) {
      var entry = createLogEntryText(JSON.parse(logEntries[i]));
      if (entry)
        container.appendChild(entry);
    }
  };

  /**
   * Create a cell with a button for expanding a network state table row.
   *
   * @param {dictionary} state Property values for the network or favorite.
   * @return {DOMElement} The created td element that displays the given value.
   */
  var createStateTableExpandButton = function(state) {
    var cell = document.createElement('td');
    cell.className = 'state-table-expand-button-cell';
    var button = document.createElement('button');
    button.addEventListener('click', function(event) {
      toggleExpandRow(event.target, state);
    });
    button.className = 'state-table-expand-button';
    cell.appendChild(button);
    return cell;
  };

  /**
   * Create a cell in network state table.
   *
   * @param {string} value Content in the cell.
   * @return {DOMElement} The created td element that displays the given value.
   */
  var createStateTableCell = function(value) {
    var cell = document.createElement('td');
    cell.textContent = value || '';
    return cell;
  };

  /**
   * Create a row in the network state table.
   *
   * @param {string} stateFields The state fields to use for the row.
   * @param {string} path The network or favorite path.
   * @param {dictionary} state Property values for the network or favorite.
   * @return {DOMElement} The created tr element that contains the network
   *     state information.
   */
  var createStateTableRow = function(stateFields, path, state) {
    var row = document.createElement('tr');
    row.className = 'state-table-row';
    row.appendChild(createStateTableExpandButton(state));
    row.appendChild(createStateTableCell(path));
    var guid = state['GUID'];
    if (guid)
      guid = guid.slice(1, 9);
    row.appendChild(createStateTableCell(guid));
    for (var i = 0; i < stateFields.length; ++i) {
      var field = stateFields[i];
      var value = '';
      if (typeof field == 'string') {
        value = state[field];
      } else {
        for (var j = 0; j < field.length; ++j) {
          value = state[field[j]];
          if (value)
            break;
        }
      }
      row.appendChild(createStateTableCell(value));
    }
    return row;
  };

  /**
   * Create table for networks or favorites.
   *
   * @param {string} tablename The name of the table to be created.
   * @param {Array.<Object>} stateFields The list of fields for the table.
   * @param {Array.<Object>} states An array of network or favorite states.
   */
  var createStateTable = function(tablename, stateFields, states) {
    var table = $(tablename);
    var oldRows = table.querySelectorAll('.state-table-row');
    for (var i = 0; i < oldRows.length; ++i)
      table.removeChild(oldRows[i]);
    for (var path in states)
      table.appendChild(createStateTableRow(stateFields, path, states[path]));
  };

  /**
   * This callback function is triggered when the data is received.
   *
   * @param {dictionary} data A dictionary that contains network state
   *     information.
   */
  var onNetworkInfoReceived = function(data) {
    createEventLog(JSON.parse(data.networkEventLog));
    createStateTable(
        'network-state-table', NETWORK_STATE_FIELDS, data.networkStates);
    createStateTable(
        'favorite-state-table', FAVORITE_STATE_FIELDS, data.favoriteStates);
  };

  /**
   * Toggle the button state and add or remove a row displaying the complete
   * state information for a row.
   *
   * @param {DOMElement} btn The button that was clicked.
   * @param {dictionary} state Property values for the network or favorite.
   */
  var toggleExpandRow = function(btn, state) {
    var cell = btn.parentNode;
    var row = cell.parentNode;
    if (btn.classList.contains('state-table-expand-button-expanded')) {
      btn.classList.remove('state-table-expand-button-expanded');
      row.parentNode.removeChild(row.nextSibling);
    } else {
      btn.classList.add('state-table-expand-button-expanded');
      var expandedRow = createExpandedRow(state, row);
      row.parentNode.insertBefore(expandedRow, row.nextSibling);
    }
  };

  /**
   * Creates the expanded row for displaying the complete state as JSON.
   *
   * @param {dictionary} state Property values for the network or favorite.
   * @param {DOMElement} baseRow The unexpanded row associated with the new row.
   * @return {DOMElement} The created tr element for the expanded row.
   */
  var createExpandedRow = function(state, baseRow) {
    var expandedRow = document.createElement('tr');
    expandedRow.className = 'state-table-row';
    var emptyCell = document.createElement('td');
    emptyCell.style.border = 'none';
    expandedRow.appendChild(emptyCell);
    var detailCell = document.createElement('td');
    detailCell.className = 'state-table-expanded-cell';
    detailCell.colSpan = baseRow.childNodes.length - 1;
    detailCell.innerHTML = JSON.stringify(state, null, '\t');
    expandedRow.appendChild(detailCell);
    return expandedRow;
  };

  /**
   * Sends a refresh request.
   */
  var sendRefresh = function() {
    chrome.send('requestNetworkInfo');
  };

  /**
   * Sets refresh rate if the interval is found in the url.
   */
  var setRefresh = function() {
    var interval = parseQueryParams(window.location)['refresh'];
    if (interval && interval != '')
      setInterval(sendRefresh, parseInt(interval) * 1000);
  };

  /**
   * Get network information from WebUI.
   */
  document.addEventListener('DOMContentLoaded', function() {
    $('log-refresh').onclick = sendRefresh;
    $('log-error').checked = true;
    $('log-error').onclick = sendRefresh;
    $('log-user').checked = true;
    $('log-user').onclick = sendRefresh;
    $('log-event').checked = true;
    $('log-event').onclick = sendRefresh;
    $('log-debug').checked = false;
    $('log-debug').onclick = sendRefresh;
    $('log-fileinfo').checked = false;
    $('log-fileinfo').onclick = sendRefresh;
    $('log-timedetail').checked = false;
    $('log-timedetail').onclick = sendRefresh;
    setRefresh();
    sendRefresh();
  });

  return {
    onNetworkInfoReceived: onNetworkInfoReceived
  };
}();