internet_detail.js revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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
5cr.define('options.internet', function() {
6  var OptionsPage = options.OptionsPage;
7  /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
8  /** @const */ var IPAddressField = options.internet.IPAddressField;
9
10  /**
11   * Network settings constants. These enums must match their C++
12   * counterparts.
13   */
14  function Constants() {}
15
16  // Network types:
17  Constants.TYPE_UNKNOWN = 0;
18  Constants.TYPE_ETHERNET = 1;
19  Constants.TYPE_WIFI = 2;
20  Constants.TYPE_WIMAX = 3;
21  Constants.TYPE_BLUETOOTH = 4;
22  Constants.TYPE_CELLULAR = 5;
23  Constants.TYPE_VPN = 6;
24
25  /*
26   * Helper function to set hidden attribute for elements matching a selector.
27   * @param {string} selector CSS selector for extracting a list of elements.
28   * @param {bool} hidden New hidden value.
29   */
30  function updateHidden(selector, hidden) {
31    var elements = cr.doc.querySelectorAll(selector);
32    for (var i = 0, el; el = elements[i]; i++) {
33      el.hidden = hidden;
34    }
35  }
36
37  /*
38   * Helper function to update the properties of the data object from the
39   * properties in the update object.
40   * @param {object} data object to update.
41   * @param {object} object containing the updated properties.
42   */
43  function updateDataObject(data, update) {
44    for (prop in update) {
45      if (prop in data)
46        data[prop] = update[prop];
47    }
48  }
49
50  /**
51   * Monitor pref change of given element.
52   * @param {Element} el Target element.
53   */
54  function observePrefsUI(el) {
55    Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate);
56  }
57
58  /**
59   * UI pref change handler.
60   * @param {Event} e The update event.
61   */
62  function handlePrefUpdate(e) {
63    DetailsInternetPage.getInstance().updateControls();
64  }
65
66  /////////////////////////////////////////////////////////////////////////////
67  // DetailsInternetPage class:
68
69  /**
70   * Encapsulated handling of ChromeOS internet details overlay page.
71   * @constructor
72   */
73  function DetailsInternetPage() {
74    OptionsPage.call(this,
75                     'detailsInternetPage',
76                     null,
77                     'details-internet-page');
78  }
79
80  cr.addSingletonGetter(DetailsInternetPage);
81
82  DetailsInternetPage.prototype = {
83    __proto__: OptionsPage.prototype,
84
85    /**
86     * Initializes DetailsInternetPage page.
87     * Calls base class implementation to starts preference initialization.
88     */
89    initializePage: function() {
90      OptionsPage.prototype.initializePage.call(this);
91      var params = parseQueryParams(window.location);
92      this.initializePageContents_(params);
93      this.showNetworkDetails_(params);
94    },
95
96    /**
97     * Auto-activates the network details dialog if network information
98     * is included in the URL.
99     */
100    showNetworkDetails_: function(params) {
101      var servicePath = params.servicePath;
102      var networkType = params.networkType;
103      if (!servicePath || !servicePath.length ||
104          !networkType || !networkType.length)
105        return;
106      chrome.send('networkCommand',
107          [networkType, servicePath, 'options']);
108    },
109
110
111    /**
112     * Initializes the contents of the page.
113     */
114    initializePageContents_: function(params) {
115      $('details-internet-dismiss').addEventListener('click', function(event) {
116        DetailsInternetPage.setDetails();
117      });
118
119      $('details-internet-login').addEventListener('click', function(event) {
120        DetailsInternetPage.setDetails();
121        DetailsInternetPage.loginFromDetails();
122      });
123
124      $('details-internet-disconnect').addEventListener('click',
125                                                        function(event) {
126        DetailsInternetPage.setDetails();
127        DetailsInternetPage.disconnectNetwork();
128      });
129
130      $('activate-details').addEventListener('click', function(event) {
131        DetailsInternetPage.activateFromDetails();
132      });
133
134      $('buyplan-details').addEventListener('click', function(event) {
135        var data = $('connection-state').data;
136        chrome.send('buyDataPlan', [data.servicePath]);
137        OptionsPage.closeOverlay();
138      });
139
140      $('view-account-details').addEventListener('click', function(event) {
141        var data = $('connection-state').data;
142        chrome.send('showMorePlanInfo', [data.servicePath]);
143        OptionsPage.closeOverlay();
144      });
145
146      $('cellular-apn-use-default').addEventListener('click', function(event) {
147        var data = $('connection-state').data;
148        var apnSelector = $('select-apn');
149
150        if (data.userApnIndex != -1) {
151          apnSelector.remove(data.userApnIndex);
152          data.userApnIndex = -1;
153        }
154
155        if (data.providerApnList.value.length > 0) {
156          var iApn = 0;
157          data.apn.apn = data.providerApnList.value[iApn].apn;
158          data.apn.username = data.providerApnList.value[iApn].username;
159          data.apn.password = data.providerApnList.value[iApn].password;
160          chrome.send('setApn', [data.servicePath,
161                                 String(data.apn.apn),
162                                 String(data.apn.username),
163                                 String(data.apn.password)]);
164          apnSelector.selectedIndex = iApn;
165          data.selectedApn = iApn;
166        } else {
167          data.apn.apn = '';
168          data.apn.username = '';
169          data.apn.password = '';
170          apnSelector.selectedIndex = -1;
171          data.selectedApn = -1;
172        }
173        updateHidden('.apn-list-view', false);
174        updateHidden('.apn-details-view', true);
175      });
176
177      $('cellular-apn-set').addEventListener('click', function(event) {
178        if ($('cellular-apn').value == '')
179          return;
180
181        var data = $('connection-state').data;
182        var apnSelector = $('select-apn');
183
184        data.apn.apn = String($('cellular-apn').value);
185        data.apn.username = String($('cellular-apn-username').value);
186        data.apn.password = String($('cellular-apn-password').value);
187        chrome.send('setApn', [data.servicePath,
188                               String(data.apn.apn),
189                               String(data.apn.username),
190                               String(data.apn.password)]);
191
192        if (data.userApnIndex != -1) {
193          apnSelector.remove(data.userApnIndex);
194          data.userApnIndex = -1;
195        }
196
197        var option = document.createElement('option');
198        option.textContent = data.apn.apn;
199        option.value = -1;
200        option.selected = true;
201        apnSelector.add(option, apnSelector[apnSelector.length - 1]);
202        data.userApnIndex = apnSelector.length - 2;
203        data.selectedApn = data.userApnIndex;
204
205        updateHidden('.apn-list-view', false);
206        updateHidden('.apn-details-view', true);
207      });
208
209      $('cellular-apn-cancel').addEventListener('click', function(event) {
210        $('select-apn').selectedIndex = $('connection-state').data.selectedApn;
211        updateHidden('.apn-list-view', false);
212        updateHidden('.apn-details-view', true);
213      });
214
215      $('select-apn').addEventListener('change', function(event) {
216        var data = $('connection-state').data;
217        var apnSelector = $('select-apn');
218        if (apnSelector[apnSelector.selectedIndex].value != -1) {
219          var apnList = data.providerApnList.value;
220          chrome.send('setApn', [data.servicePath,
221              String(apnList[apnSelector.selectedIndex].apn),
222              String(apnList[apnSelector.selectedIndex].username),
223              String(apnList[apnSelector.selectedIndex].password)
224          ]);
225          data.selectedApn = apnSelector.selectedIndex;
226        } else if (apnSelector.selectedIndex == data.userApnIndex) {
227          chrome.send('setApn', [data.servicePath,
228                                 String(data.apn.apn),
229                                 String(data.apn.username),
230                                 String(data.apn.password)]);
231          data.selectedApn = apnSelector.selectedIndex;
232        } else {
233          $('cellular-apn').value = data.apn.apn;
234          $('cellular-apn-username').value = data.apn.username;
235          $('cellular-apn-password').value = data.apn.password;
236
237          updateHidden('.apn-list-view', true);
238          updateHidden('.apn-details-view', false);
239        }
240      });
241
242      $('sim-card-lock-enabled').addEventListener('click', function(event) {
243        var newValue = $('sim-card-lock-enabled').checked;
244        // Leave value as is because user needs to enter PIN code first.
245        // When PIN will be entered and value changed,
246        // we'll update UI to reflect that change.
247        $('sim-card-lock-enabled').checked = !newValue;
248        chrome.send('setSimCardLock', [newValue]);
249      });
250      $('change-pin').addEventListener('click', function(event) {
251        chrome.send('changePin');
252      });
253
254      // Proxy
255      options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list'));
256      $('remove-host').addEventListener('click',
257                                        this.handleRemoveProxyExceptions_);
258      $('add-host').addEventListener('click', this.handleAddProxyException_);
259      $('direct-proxy').addEventListener('click', this.disableManualProxy_);
260      $('manual-proxy').addEventListener('click', this.enableManualProxy_);
261      $('auto-proxy').addEventListener('click', this.disableManualProxy_);
262      $('proxy-all-protocols').addEventListener('click',
263                                                this.toggleSingleProxy_);
264
265      observePrefsUI($('direct-proxy'));
266      observePrefsUI($('manual-proxy'));
267      observePrefsUI($('auto-proxy'));
268      observePrefsUI($('proxy-all-protocols'));
269
270      $('ip-automatic-configuration-checkbox').addEventListener('click',
271        this.handleIpAutoConfig_);
272      $('automatic-dns-radio').addEventListener('click',
273        this.handleNameServerTypeChange_);
274      $('google-dns-radio').addEventListener('click',
275        this.handleNameServerTypeChange_);
276      $('user-dns-radio').addEventListener('click',
277        this.handleNameServerTypeChange_);
278
279      $('google-dns-label').innerHTML =
280        loadTimeData.getString('googleNameServers');
281    },
282
283    /**
284     * Handler for "add" event fired from userNameEdit.
285     * @param {Event} e Add event fired from userNameEdit.
286     * @private
287     */
288    handleAddProxyException_: function(e) {
289      var exception = $('new-host').value;
290      $('new-host').value = '';
291
292      exception = exception.trim();
293      if (exception)
294        $('ignored-host-list').addException(exception);
295    },
296
297    /**
298     * Handler for when the remove button is clicked
299     * @param {Event} e The click event.
300     * @private
301     */
302    handleRemoveProxyExceptions_: function(e) {
303      var selectedItems = $('ignored-host-list').selectedItems;
304      for (var x = 0; x < selectedItems.length; x++) {
305        $('ignored-host-list').removeException(selectedItems[x]);
306      }
307    },
308
309    /**
310     * Handler for when the IP automatic configuration checkbox is clicked.
311     * @param {Event} e The click event.
312     * @private
313     */
314    handleIpAutoConfig_: function(e) {
315      var checked = $('ip-automatic-configuration-checkbox').checked;
316      var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
317      for (var i = 0; i < fields.length; ++i) {
318        fields[i].editable = !checked;
319        if (checked) {
320          var model = fields[i].model;
321          model.value = model.automatic;
322          fields[i].model = model;
323        }
324      }
325      if (!checked)
326        $('ip-address').focus();
327    },
328
329    /**
330     * Handler for when the name server selection changes.
331     * @param {Event} e The click event.
332     * @private
333     */
334    handleNameServerTypeChange_: function(event) {
335      var type = event.target.value;
336      DetailsInternetPage.updateNameServerDisplay(type);
337    },
338
339    /**
340     * Update details page controls.
341     * @private
342     */
343    updateControls: function() {
344      // Only show ipconfig section if network is connected OR if nothing on
345      // this device is connected. This is so that you can fix the ip configs
346      // if you can't connect to any network.
347      // TODO(chocobo): Once ipconfig is moved to flimflam service objects,
348      //   we need to redo this logic to allow configuration of all networks.
349      $('ipconfig-section').hidden = !this.connected && this.deviceConnected;
350      $('ipconfig-dns-section').hidden =
351        !this.connected && this.deviceConnected;
352
353      // Network type related.
354      updateHidden('#details-internet-page .cellular-details', !this.cellular);
355      updateHidden('#details-internet-page .wifi-details', !this.wireless);
356      updateHidden('#details-internet-page .wimax-details', !this.wimax);
357      updateHidden('#details-internet-page .vpn-details', !this.vpn);
358      updateHidden('#details-internet-page .proxy-details', !this.showProxy);
359      /* Network information merged into the Wifi tab for wireless networks
360         unless the option is set for enabling a static IP configuration. */
361      updateHidden('#details-internet-page .network-details',
362                   (this.wireless && !this.showStaticIPConfig) || this.vpn);
363      updateHidden('#details-internet-page .wifi-network-setting',
364                   this.showStaticIPConfig);
365
366      // Wifi - Password and shared.
367      updateHidden('#details-internet-page #password-details',
368                   !this.wireless || !this.password);
369      updateHidden('#details-internet-page #wifi-shared-network',
370          !this.shared);
371      updateHidden('#details-internet-page #prefer-network',
372                   !this.showPreferred);
373
374      // WiMAX.
375      updateHidden('#details-internet-page #wimax-shared-network',
376        !this.shared);
377
378      // Proxy
379      this.updateProxyBannerVisibility_();
380      this.toggleSingleProxy_();
381      if ($('manual-proxy').checked)
382        this.enableManualProxy_();
383      else
384        this.disableManualProxy_();
385    },
386
387    /**
388     * Updates info banner visibility state. This function shows the banner
389     * if proxy is managed or shared-proxies is off for shared network.
390     * @private
391     */
392    updateProxyBannerVisibility_: function() {
393      var bannerDiv = $('info-banner');
394      // Show banner and determine its message if necessary.
395      var controlledBy = $('direct-proxy').controlledBy;
396      if (!controlledBy || controlledBy == '') {
397        bannerDiv.hidden = true;
398      } else {
399        bannerDiv.hidden = false;
400        // The possible banner texts are loaded in proxy_handler.cc.
401        var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() +
402                         controlledBy.slice(1);
403        $('banner-text').textContent = loadTimeData.getString(bannerText);
404      }
405    },
406
407    /**
408     * Handler for when the user clicks on the checkbox to allow a
409     * single proxy usage.
410     * @private
411     * @param {Event} e Click Event.
412     */
413    toggleSingleProxy_: function(e) {
414      if ($('proxy-all-protocols').checked) {
415        $('multi-proxy').hidden = true;
416        $('single-proxy').hidden = false;
417      } else {
418        $('multi-proxy').hidden = false;
419        $('single-proxy').hidden = true;
420      }
421    },
422
423    /**
424     * Handler for selecting a radio button that will disable the manual
425     * controls.
426     * @private
427     * @param {Event} e Click event.
428     */
429    disableManualProxy_: function(e) {
430      $('advanced-config').hidden = true;
431      $('proxy-all-protocols').disabled = true;
432      $('proxy-host-name').disabled = true;
433      $('proxy-host-port').disabled = true;
434      $('proxy-host-single-name').disabled = true;
435      $('proxy-host-single-port').disabled = true;
436      $('secure-proxy-host-name').disabled = true;
437      $('secure-proxy-port').disabled = true;
438      $('ftp-proxy').disabled = true;
439      $('ftp-proxy-port').disabled = true;
440      $('socks-host').disabled = true;
441      $('socks-port').disabled = true;
442      $('proxy-config').disabled = $('auto-proxy').disabled ||
443                                   !$('auto-proxy').checked;
444    },
445
446    /**
447     * Handler for selecting a radio button that will enable the manual
448     * controls.
449     * @private
450     * @param {Event} e Click event.
451     */
452    enableManualProxy_: function(e) {
453      $('advanced-config').hidden = false;
454      $('ignored-host-list').redraw();
455      var allDisabled = $('manual-proxy').disabled;
456      $('new-host').disabled = allDisabled;
457      $('remove-host').disabled = allDisabled;
458      $('add-host').disabled = allDisabled;
459      $('proxy-all-protocols').disabled = allDisabled;
460      $('proxy-host-name').disabled = allDisabled;
461      $('proxy-host-port').disabled = allDisabled;
462      $('proxy-host-single-name').disabled = allDisabled;
463      $('proxy-host-single-port').disabled = allDisabled;
464      $('secure-proxy-host-name').disabled = allDisabled;
465      $('secure-proxy-port').disabled = allDisabled;
466      $('ftp-proxy').disabled = allDisabled;
467      $('ftp-proxy-port').disabled = allDisabled;
468      $('socks-host').disabled = allDisabled;
469      $('socks-port').disabled = allDisabled;
470      $('proxy-config').disabled = true;
471    },
472  };
473
474  /**
475   * Enables or Disables all buttons that provide operations on the cellular
476   * network.
477   */
478  DetailsInternetPage.changeCellularButtonsState = function(disable) {
479    var buttonsToDisableList =
480        new Array('details-internet-login',
481                  'details-internet-disconnect',
482                  'activate-details',
483                  'buyplan-details',
484                  'view-account-details');
485
486    for (var i = 0; i < buttonsToDisableList.length; ++i) {
487      button = $(buttonsToDisableList[i]);
488      button.disabled = disable;
489    }
490  };
491
492  /**
493   * Shows a spinner while the carrier is changed.
494   */
495  DetailsInternetPage.showCarrierChangeSpinner = function(visible) {
496    $('switch-carrier-spinner').hidden = !visible;
497    // Disable any buttons that allow us to operate on cellular networks.
498    DetailsInternetPage.changeCellularButtonsState(visible);
499  };
500
501  /**
502   * Changes the network carrier.
503   */
504  DetailsInternetPage.handleCarrierChanged = function() {
505    var carrierSelector = $('select-carrier');
506    var carrier = carrierSelector[carrierSelector.selectedIndex].textContent;
507    DetailsInternetPage.showCarrierChangeSpinner(true);
508    var data = $('connection-state').data;
509    chrome.send('setCarrier', [data.servicePath, carrier]);
510  };
511
512  /**
513   * Performs minimal initialization of the InternetDetails dialog in
514   * preparation for showing proxy-setttings.
515   */
516  DetailsInternetPage.initializeProxySettings = function() {
517    var detailsPage = DetailsInternetPage.getInstance();
518    detailsPage.initializePageContents_();
519  };
520
521  /**
522   * Displays the InternetDetails dialog with only the proxy settings visible.
523   */
524  DetailsInternetPage.showProxySettings = function() {
525    var detailsPage = DetailsInternetPage.getInstance();
526    $('network-details-header').hidden = true;
527    $('buyplan-details').hidden = true;
528    $('activate-details').hidden = true;
529    $('view-account-details').hidden = true;
530    detailsPage.cellular = false;
531    detailsPage.wireless = false;
532    detailsPage.vpn = false;
533    detailsPage.showProxy = true;
534    updateHidden('#internet-tab', true);
535    updateHidden('#details-tab-strip', true);
536    updateHidden('#details-internet-page .action-area', true);
537    detailsPage.updateControls();
538    detailsPage.visible = true;
539  };
540
541  DetailsInternetPage.updateProxySettings = function(type) {
542      var proxyHost = null,
543          proxyPort = null;
544
545      if (type == 'cros.session.proxy.singlehttp') {
546        proxyHost = 'proxy-host-single-name';
547        proxyPort = 'proxy-host-single-port';
548      }else if (type == 'cros.session.proxy.httpurl') {
549        proxyHost = 'proxy-host-name';
550        proxyPort = 'proxy-host-port';
551      }else if (type == 'cros.session.proxy.httpsurl') {
552        proxyHost = 'secure-proxy-host-name';
553        proxyPort = 'secure-proxy-port';
554      }else if (type == 'cros.session.proxy.ftpurl') {
555        proxyHost = 'ftp-proxy';
556        proxyPort = 'ftp-proxy-port';
557      }else if (type == 'cros.session.proxy.socks') {
558        proxyHost = 'socks-host';
559        proxyPort = 'socks-port';
560      }else {
561        return;
562      }
563
564      var hostValue = $(proxyHost).value;
565      if (hostValue.indexOf(':') !== -1) {
566        if (hostValue.match(/:/g).length == 1) {
567          hostValue = hostValue.split(':');
568          $(proxyHost).value = hostValue[0];
569          $(proxyPort).value = hostValue[1];
570        }
571      }
572  };
573
574  DetailsInternetPage.updateCarrier = function() {
575    DetailsInternetPage.showCarrierChangeSpinner(false);
576  };
577
578  DetailsInternetPage.updateSecurityTab = function(requirePin) {
579    $('sim-card-lock-enabled').checked = requirePin;
580    $('change-pin').hidden = !requirePin;
581  };
582
583  DetailsInternetPage.loginFromDetails = function() {
584    var data = $('connection-state').data;
585    var servicePath = data.servicePath;
586    chrome.send('networkCommand', [String(data.type),
587                                          servicePath,
588                                          'connect']);
589    OptionsPage.closeOverlay();
590  };
591
592  DetailsInternetPage.disconnectNetwork = function() {
593    var data = $('connection-state').data;
594    var servicePath = data.servicePath;
595    chrome.send('networkCommand', [String(data.type),
596                                          servicePath,
597                                          'disconnect']);
598    OptionsPage.closeOverlay();
599  };
600
601  DetailsInternetPage.activateFromDetails = function() {
602    var data = $('connection-state').data;
603    var servicePath = data.servicePath;
604    if (data.type == Constants.TYPE_CELLULAR) {
605      chrome.send('networkCommand', [String(data.type),
606                                            servicePath,
607                                            'activate']);
608    }
609    OptionsPage.closeOverlay();
610  };
611
612  DetailsInternetPage.setDetails = function() {
613    var data = $('connection-state').data;
614    var servicePath = data.servicePath;
615    if (data.type == Constants.TYPE_WIFI) {
616      chrome.send('setPreferNetwork',
617                   [servicePath,
618                    $('prefer-network-wifi').checked ? 'true' : 'false']);
619      chrome.send('setAutoConnect',
620                  [servicePath,
621                   $('auto-connect-network-wifi').checked ? 'true' : 'false']);
622    } else if (data.type == Constants.TYPE_WIMAX) {
623      chrome.send('setAutoConnect',
624                  [servicePath,
625                   $('auto-connect-network-wimax').checked ? 'true' : 'false']);
626    } else if (data.type == Constants.TYPE_CELLULAR) {
627      chrome.send('setAutoConnect',
628                  [servicePath,
629                   $('auto-connect-network-cellular').checked ? 'true' :
630                       'false']);
631    } else if (data.type == Constants.TYPE_VPN) {
632      chrome.send('setServerHostname',
633                  [servicePath,
634                   $('inet-server-hostname').value]);
635      chrome.send('setAutoConnect',
636                  [servicePath,
637                   $('auto-connect-network-vpn').checked ? 'true' : 'false']);
638    }
639
640    var nameServerTypes = ['automatic', 'google', 'user'];
641    var nameServerType = 'automatic';
642    for (var i = 0; i < nameServerTypes.length; ++i) {
643      if ($(nameServerTypes[i] + '-dns-radio').checked) {
644        nameServerType = nameServerTypes[i];
645        break;
646      }
647    }
648
649    // Skip any empty values.
650    var userNameServers = [];
651    for (var i = 1; i <= 4; ++i) {
652      var nameServerField = $('ipconfig-dns' + i);
653      if (nameServerField && nameServerField.model &&
654          nameServerField.model.value) {
655        userNameServers.push(nameServerField.model.value);
656      }
657    }
658
659    userNameServers = userNameServers.join(',');
660
661    chrome.send('setIPConfig',
662                [servicePath,
663                 Boolean($('ip-automatic-configuration-checkbox').checked),
664                 $('ip-address').model.value || '',
665                 $('ip-netmask').model.value || '',
666                 $('ip-gateway').model.value || '',
667                 nameServerType,
668                 userNameServers]);
669    OptionsPage.closeOverlay();
670  };
671
672  DetailsInternetPage.updateNameServerDisplay = function(type) {
673    var editable = type == 'user';
674    var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'),
675                  $('ipconfig-dns3'), $('ipconfig-dns4')];
676    for (var i = 0; i < fields.length; ++i) {
677      fields[i].editable = editable;
678    }
679    if (editable)
680      $('ipconfig-dns1').focus();
681
682    var automaticDns = $('automatic-dns-display');
683    var googleDns = $('google-dns-display');
684    var userDns = $('user-dns-settings');
685    switch (type) {
686      case 'automatic':
687        automaticDns.setAttribute('selected', '');
688        googleDns.removeAttribute('selected');
689        userDns.removeAttribute('selected');
690        break;
691      case 'google':
692        automaticDns.removeAttribute('selected');
693        googleDns.setAttribute('selected', '');
694        userDns.removeAttribute('selected');
695        break;
696      case 'user':
697        automaticDns.removeAttribute('selected');
698        googleDns.removeAttribute('selected');
699        userDns.setAttribute('selected', '');
700        break;
701    }
702  };
703
704  DetailsInternetPage.updateConnectionData = function(update) {
705    var detailsPage = DetailsInternetPage.getInstance();
706    if (!detailsPage.visible)
707      return;
708
709    var data = $('connection-state').data;
710    if (!data)
711      return;
712
713    // Update our cached data object.
714    updateDataObject(data, update);
715
716    detailsPage.deviceConnected = data.deviceConnected;
717    detailsPage.connecting = data.connecting;
718    detailsPage.connected = data.connected;
719    $('connection-state').textContent = data.connectionState;
720
721    $('details-internet-login').hidden = data.connected;
722    $('details-internet-login').disabled = data.disableConnectButton;
723
724    if (data.type == Constants.TYPE_WIFI) {
725      $('wifi-connection-state').textContent = data.connectionState;
726    } else if (data.type == Constants.TYPE_WIMAX) {
727      $('wimax-connection-state').textContent = data.connectionState;
728    } else if (data.type == Constants.TYPE_CELLULAR) {
729      $('activation-state').textContent = data.activationState;
730
731      $('buyplan-details').hidden = !data.showBuyButton;
732      $('view-account-details').hidden = !data.showViewAccountButton;
733
734      $('activate-details').hidden = !data.showActivateButton;
735      if (data.showActivateButton)
736        $('details-internet-login').hidden = true;
737    }
738
739    if (data.type != Constants.TYPE_ETHERNET)
740      $('details-internet-disconnect').hidden = !data.connected;
741
742    $('connection-state').data = data;
743  }
744
745  DetailsInternetPage.showDetailedInfo = function(data) {
746    var detailsPage = DetailsInternetPage.getInstance();
747
748    // Populate header
749    $('network-details-title').textContent = data.networkName;
750    var statusKey = data.connected ? 'networkConnected' :
751                                     'networkNotConnected';
752    $('network-details-subtitle-status').textContent =
753        loadTimeData.getString(statusKey);
754    var typeKey = null;
755    switch (data.type) {
756    case Constants.TYPE_ETHERNET:
757      typeKey = 'ethernetTitle';
758      break;
759    case Constants.TYPE_WIFI:
760      typeKey = 'wifiTitle';
761      break;
762    case Constants.TYPE_WIMAX:
763      typeKey = 'wimaxTitle';
764      break;
765    case Constants.TYPE_CELLULAR:
766      typeKey = 'cellularTitle';
767      break;
768    case Constants.TYPE_VPN:
769      typeKey = 'vpnTitle';
770      break;
771    }
772    var typeLabel = $('network-details-subtitle-type');
773    var typeSeparator = $('network-details-subtitle-separator');
774    if (typeKey) {
775      typeLabel.textContent = loadTimeData.getString(typeKey);
776      typeLabel.hidden = false;
777      typeSeparator.hidden = false;
778    } else {
779      typeLabel.hidden = true;
780      typeSeparator.hidden = true;
781    }
782
783    // TODO(chocobo): Is this hack to cache the data here reasonable?
784    // TODO(kevers): Find more appropriate place to cache data.
785    $('connection-state').data = data;
786
787    $('buyplan-details').hidden = true;
788    $('activate-details').hidden = true;
789    $('view-account-details').hidden = true;
790    $('details-internet-login').hidden = data.connected;
791    $('details-internet-login').disabled = data.disableConnectButton;
792    if (data.type == Constants.TYPE_ETHERNET)
793      $('details-internet-disconnect').hidden = true;
794    else
795      $('details-internet-disconnect').hidden = !data.connected;
796
797    detailsPage.deviceConnected = data.deviceConnected;
798    detailsPage.connecting = data.connecting;
799    detailsPage.connected = data.connected;
800    detailsPage.showProxy = data.showProxy;
801    detailsPage.showStaticIPConfig = data.showStaticIPConfig;
802    $('connection-state').textContent = data.connectionState;
803
804    var ipAutoConfig = data.ipAutoConfig ? 'automatic' : 'user';
805    $('ip-automatic-configuration-checkbox').checked = data.ipAutoConfig;
806    var inetAddress = {autoConfig: ipAutoConfig};
807    var inetNetmask = {autoConfig: ipAutoConfig};
808    var inetGateway = {autoConfig: ipAutoConfig};
809
810    if (data.ipconfig.value) {
811      inetAddress.automatic = data.ipconfig.value.address;
812      inetAddress.value = data.ipconfig.value.address;
813      inetNetmask.automatic = data.ipconfig.value.netmask;
814      inetNetmask.value = data.ipconfig.value.netmask;
815      inetGateway.automatic = data.ipconfig.value.gateway;
816      inetGateway.value = data.ipconfig.value.gateway;
817    }
818
819    // Override the "automatic" values with the real saved DHCP values,
820    // if they are set.
821    if (data.savedIP.address) {
822      inetAddress.automatic = data.savedIP.address;
823      inetAddress.value = data.savedIP.address;
824    }
825    if (data.savedIP.netmask) {
826      inetNetmask.automatic = data.savedIP.netmask;
827      inetNetmask.value = data.savedIP.netmask;
828    }
829    if (data.savedIP.gateway) {
830      inetGateway.automatic = data.savedIP.gateway;
831      inetGateway.value = data.savedIP.gateway;
832    }
833
834    if (ipAutoConfig == 'user') {
835      if (data.staticIP.value.address) {
836        inetAddress.value = data.staticIP.value.address;
837        inetAddress.user = data.staticIP.value.address;
838      }
839      if (data.staticIP.value.netmask) {
840        inetNetmask.value = data.staticIP.value.netmask;
841        inetNetmask.user = data.staticIP.value.netmask;
842      }
843      if (data.staticIP.value.gateway) {
844        inetGateway.value = data.staticIP.value.gateway;
845        inetGateway.user = data.staticIP.value.gateway;
846      }
847    }
848
849    var configureAddressField = function(field, model) {
850      IPAddressField.decorate(field);
851      field.model = model;
852      field.editable = model.autoConfig == 'user';
853    };
854
855    configureAddressField($('ip-address'), inetAddress);
856    configureAddressField($('ip-netmask'), inetNetmask);
857    configureAddressField($('ip-gateway'), inetGateway);
858
859    var inetNameServers = '';
860    if (data.ipconfig.value && data.ipconfig.value.nameServers) {
861      inetNameServers = data.ipconfig.value.nameServers;
862      $('automatic-dns-display').textContent = inetNameServers;
863    }
864
865    if (data.savedIP && data.savedIP.nameServers)
866      $('automatic-dns-display').textContent = data.savedIP.nameServers;
867
868    if (data.nameServersGoogle)
869      $('google-dns-display').textContent = data.nameServersGoogle;
870
871    var nameServersUser = [];
872    if (data.staticIP.value.nameServers)
873      nameServersUser = data.staticIP.value.nameServers.split(',');
874
875    var nameServerModels = [];
876    for (var i = 0; i < 4; ++i)
877      nameServerModels.push({value: nameServersUser[i] || ''});
878
879    $(data.nameServerType + '-dns-radio').checked = true;
880    configureAddressField($('ipconfig-dns1'), nameServerModels[0]);
881    configureAddressField($('ipconfig-dns2'), nameServerModels[1]);
882    configureAddressField($('ipconfig-dns3'), nameServerModels[2]);
883    configureAddressField($('ipconfig-dns4'), nameServerModels[3]);
884
885    DetailsInternetPage.updateNameServerDisplay(data.nameServerType);
886
887    if (data.hardwareAddress) {
888      $('hardware-address').textContent = data.hardwareAddress;
889      $('hardware-address-row').style.display = 'table-row';
890    } else {
891      // This is most likely a device without a hardware address.
892      $('hardware-address-row').style.display = 'none';
893    }
894    if (data.type == Constants.TYPE_WIFI) {
895      OptionsPage.showTab($('wifi-network-nav-tab'));
896      detailsPage.wireless = true;
897      detailsPage.vpn = false;
898      detailsPage.ethernet = false;
899      detailsPage.cellular = false;
900      detailsPage.gsm = false;
901      detailsPage.wimax = false;
902      detailsPage.shared = data.shared;
903      $('wifi-connection-state').textContent = data.connectionState;
904      $('wifi-ssid').textContent = data.ssid;
905      if (data.bssid && data.bssid.length > 0) {
906        $('wifi-bssid').textContent = data.bssid;
907        $('wifi-bssid-entry').hidden = false;
908      } else {
909        $('wifi-bssid-entry').hidden = true;
910      }
911      $('wifi-ip-address').textContent = inetAddress.value;
912      $('wifi-netmask').textContent = inetNetmask.value;
913      $('wifi-gateway').textContent = inetGateway.value;
914      $('wifi-name-servers').textContent = inetNameServers;
915      if (data.encryption && data.encryption.length > 0) {
916        $('wifi-security').textContent = data.encryption;
917        $('wifi-security-entry').hidden = false;
918      } else {
919        $('wifi-security-entry').hidden = true;
920      }
921      // Frequency is in MHz.
922      var frequency = loadTimeData.getString('inetFrequencyFormat');
923      frequency = frequency.replace('$1', data.frequency);
924      $('wifi-frequency').textContent = frequency;
925      // Signal strength as percentage.
926      var signalStrength = loadTimeData.getString('inetSignalStrengthFormat');
927      signalStrength = signalStrength.replace('$1', data.strength);
928      $('wifi-signal-strength').textContent = signalStrength;
929      if (data.hardwareAddress) {
930        $('wifi-hardware-address').textContent = data.hardwareAddress;
931        $('wifi-hardware-address-entry').hidden = false;
932      } else {
933        $('wifi-hardware-address-entry').hidden = true;
934      }
935      detailsPage.showPreferred = data.showPreferred;
936      $('prefer-network-wifi').checked = data.preferred.value;
937      $('prefer-network-wifi').disabled = !data.remembered;
938      $('auto-connect-network-wifi').checked = data.autoConnect.value;
939      $('auto-connect-network-wifi').disabled = !data.remembered;
940      detailsPage.password = data.encrypted;
941    } else if (data.type == Constants.TYPE_WIMAX) {
942      OptionsPage.showTab($('wimax-network-nav-tab'));
943      detailsPage.wimax = true;
944      detailsPage.wireless = false;
945      detailsPage.vpn = false;
946      detailsPage.ethernet = false;
947      detailsPage.cellular = false;
948      detailsPage.gsm = false;
949      detailsPage.shared = data.shared;
950      detailsPage.showPreferred = data.showPreferred;
951      $('wimax-connection-state').textContent = data.connectionState;
952      $('auto-connect-network-wimax').checked = data.autoConnect.value;
953      $('auto-connect-network-wimax').disabled = !data.remembered;
954      if (data.identity) {
955        $('wimax-eap-identity').textContent = data.identity;
956        $('wimax-eap-identity-entry').hidden = false;
957      } else {
958        $('wimax-eap-identity-entry').hidden = true;
959      }
960      // Signal strength as percentage.
961      var signalStrength = loadTimeData.getString('inetSignalStrengthFormat');
962      signalStrength = signalStrength.replace('$1', data.strength);
963      $('wimax-signal-strength').textContent = signalStrength;
964    } else if (data.type == Constants.TYPE_CELLULAR) {
965      OptionsPage.showTab($('cellular-conn-nav-tab'));
966      detailsPage.ethernet = false;
967      detailsPage.wireless = false;
968      detailsPage.wimax = false;
969      detailsPage.vpn = false;
970      detailsPage.cellular = true;
971      if (data.showCarrierSelect && data.currentCarrierIndex != -1) {
972        var carrierSelector = $('select-carrier');
973        carrierSelector.onchange = DetailsInternetPage.handleCarrierChanged;
974        carrierSelector.options.length = 0;
975        for (var i = 0; i < data.carriers.length; ++i) {
976          var option = document.createElement('option');
977          option.textContent = data.carriers[i];
978          carrierSelector.add(option);
979        }
980        carrierSelector.selectedIndex = data.currentCarrierIndex;
981      } else {
982        $('service-name').textContent = data.serviceName;
983      }
984
985      $('network-technology').textContent = data.networkTechnology;
986      $('activation-state').textContent = data.activationState;
987      $('roaming-state').textContent = data.roamingState;
988      $('restricted-pool').textContent = data.restrictedPool;
989      $('error-state').textContent = data.errorState;
990      $('manufacturer').textContent = data.manufacturer;
991      $('model-id').textContent = data.modelId;
992      $('firmware-revision').textContent = data.firmwareRevision;
993      $('hardware-revision').textContent = data.hardwareRevision;
994      $('prl-version').textContent = data.prlVersion;
995      $('meid').textContent = data.meid;
996      $('imei').textContent = data.imei;
997      $('mdn').textContent = data.mdn;
998      $('esn').textContent = data.esn;
999      $('min').textContent = data.min;
1000      detailsPage.gsm = data.gsm;
1001      if (data.gsm) {
1002        $('operator-name').textContent = data.operatorName;
1003        $('operator-code').textContent = data.operatorCode;
1004        $('imsi').textContent = data.imsi;
1005
1006        var apnSelector = $('select-apn');
1007        // Clear APN lists, keep only last element that "other".
1008        while (apnSelector.length != 1)
1009          apnSelector.remove(0);
1010        var otherOption = apnSelector[0];
1011        data.selectedApn = -1;
1012        data.userApnIndex = -1;
1013        var apnList = data.providerApnList.value;
1014        for (var i = 0; i < apnList.length; i++) {
1015          var option = document.createElement('option');
1016          var name = apnList[i].localizedName;
1017          if (name == '' && apnList[i].name != '')
1018            name = apnList[i].name;
1019          if (name == '')
1020            name = apnList[i].apn;
1021          else
1022            name = name + ' (' + apnList[i].apn + ')';
1023          option.textContent = name;
1024          option.value = i;
1025          if ((data.apn.apn == apnList[i].apn &&
1026               data.apn.username == apnList[i].username &&
1027               data.apn.password == apnList[i].password) ||
1028              (data.apn.apn == '' &&
1029               data.lastGoodApn.apn == apnList[i].apn &&
1030               data.lastGoodApn.username == apnList[i].username &&
1031               data.lastGoodApn.password == apnList[i].password)) {
1032            data.selectedApn = i;
1033          }
1034          // Insert new option before "other" option.
1035          apnSelector.add(option, otherOption);
1036        }
1037        if (data.selectedApn == -1 && data.apn.apn != '') {
1038          var option = document.createElement('option');
1039          option.textContent = data.apn.apn;
1040          option.value = -1;
1041          apnSelector.add(option, otherOption);
1042          data.selectedApn = apnSelector.length - 2;
1043          data.userApnIndex = data.selectedApn;
1044        }
1045        apnSelector.selectedIndex = data.selectedApn;
1046        updateHidden('.apn-list-view', false);
1047        updateHidden('.apn-details-view', true);
1048        DetailsInternetPage.updateSecurityTab(data.simCardLockEnabled.value);
1049      }
1050      $('auto-connect-network-cellular').checked = data.autoConnect.value;
1051      $('auto-connect-network-cellular').disabled = false;
1052
1053      $('buyplan-details').hidden = !data.showBuyButton;
1054      $('view-account-details').hidden = !data.showViewAccountButton;
1055      $('activate-details').hidden = !data.showActivateButton;
1056      if (data.showActivateButton) {
1057        $('details-internet-login').hidden = true;
1058      }
1059    } else if (data.type == Constants.TYPE_VPN) {
1060      OptionsPage.showTab($('vpn-nav-tab'));
1061      detailsPage.wireless = false;
1062      detailsPage.wimax = false;
1063      detailsPage.vpn = true;
1064      detailsPage.ethernet = false;
1065      detailsPage.cellular = false;
1066      detailsPage.gsm = false;
1067      $('inet-service-name').textContent = data.service_name;
1068      $('inet-provider-type').textContent = data.provider_type;
1069      $('inet-username').textContent = data.username;
1070      var inetServerHostname = $('inet-server-hostname');
1071      inetServerHostname.value = data.serverHostname.value;
1072      inetServerHostname.resetHandler = function() {
1073        OptionsPage.hideBubble();
1074        inetServerHostname.value = data.serverHostname.recommendedValue;
1075      };
1076      $('auto-connect-network-vpn').checked = data.autoConnect.value;
1077      $('auto-connect-network-vpn').disabled = false;
1078    } else {
1079      OptionsPage.showTab($('internet-nav-tab'));
1080      detailsPage.ethernet = true;
1081      detailsPage.wireless = false;
1082      detailsPage.wimax = false;
1083      detailsPage.vpn = false;
1084      detailsPage.cellular = false;
1085      detailsPage.gsm = false;
1086    }
1087
1088    // Update controlled option indicators.
1089    indicators = cr.doc.querySelectorAll(
1090        '#details-internet-page .controlled-setting-indicator');
1091    for (var i = 0; i < indicators.length; i++) {
1092      var propName = indicators[i].getAttribute('data');
1093      if (!propName || !data[propName])
1094        continue;
1095      var propData = data[propName];
1096      // Create a synthetic pref change event decorated as
1097      // CoreOptionsHandler::CreateValueForPref() does.
1098      var event = new cr.Event(name);
1099      event.value = {
1100        value: propData.value,
1101        controlledBy: propData.controlledBy,
1102        recommendedValue: propData.recommendedValue,
1103      };
1104      indicators[i].handlePrefChange(event);
1105      var forElement = $(indicators[i].getAttribute('for'));
1106      if (forElement) {
1107        forElement.disabled = propData.controlledBy == 'policy';
1108        if (forElement.resetHandler)
1109          indicators[i].resetHandler = forElement.resetHandler;
1110      }
1111    }
1112
1113    detailsPage.updateControls();
1114
1115    // Don't show page name in address bar and in history to prevent people
1116    // navigate here by hand and solve issue with page session restore.
1117    OptionsPage.showPageByName('detailsInternetPage', false);
1118  };
1119
1120  return {
1121    DetailsInternetPage: DetailsInternetPage
1122  };
1123});
1124