internet_detail.js revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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
5// NOTE(stevenjb): This code is in the process of being converted to be
6// compatible with the networkingPrivate extension API:
7// * The network property dictionaries are being converted to use ONC values.
8// * chrome.send calls will be replaced with an API object that simulates the
9//   networkingPrivate API. See network_config.js.
10// See crbug.com/279351 for more info.
11
12cr.define('options.internet', function() {
13  var Page = cr.ui.pageManager.Page;
14  var PageManager = cr.ui.pageManager.PageManager;
15  /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
16  /** @const */ var IPAddressField = options.internet.IPAddressField;
17
18  var GetManagedTypes = {
19    ACTIVE: 0,
20    TRANSLATED: 1,
21    RECOMMENDED: 2
22  };
23
24  /**
25   * Gets the value of a property from a dictionary |data| that includes ONC
26   * managed properties, e.g. getManagedValue(data, 'Name'). See notes for
27   * getManagedProperty.
28   * @param {object} data The properties dictionary.
29   * @param {string} key The property key.
30   * @param {string} type (Optional) The type of property to get as defined in
31   *                      GetManagedTypes:
32   *                      'ACTIVE' (default)  - gets the active value
33   *                      'TRANSLATED' - gets the traslated or active value
34   *                      'RECOMMENDED' - gets the recommended value
35   * @return {*} The property value or undefined.
36   */
37  function getManagedValue(data, key, type) {
38    var property = getManagedProperty(data, key);
39    if (typeof property != 'object')
40      return property;
41    if (type == GetManagedTypes.RECOMMENDED)
42      return getRecommendedValue(property);
43    if (type == GetManagedTypes.TRANSLATED && 'Translated' in property)
44      return property['Translated'];
45    // Otherwise get the Active value (defalt behavior).
46    if ('Active' in property)
47      return property['Active'];
48    // If no Active value is defined, return the effective value.
49    return getEffectiveValue(property);
50  }
51
52  /**
53   * Get the recommended value from a Managed property ONC dictionary.
54   * @param {object} property The managed property ONC dictionary.
55   * @return {*} the effective value or undefined.
56   */
57  function getRecommendedValue(property) {
58    if (property['UserEditable'])
59      return property['UserPolicy'];
60    if (property['DeviceEditable'])
61      return property['DevicePolicy'];
62    // No value recommended by policy.
63    return undefined;
64  }
65
66  /**
67   * Get the effective value from a Managed property ONC dictionary.
68   * @param {object} property The managed property ONC dictionary.
69   * @return {*} The effective value or undefined.
70   */
71  function getEffectiveValue(property) {
72    if ('Effective' in property) {
73      var effective = property.Effective;
74      if (effective in property)
75        return property[effective];
76    }
77    return undefined;
78  }
79
80  /**
81   * Gets either a managed property dictionary or an unmanaged value from
82   * dictionary |data| that includes ONC managed properties. This supports
83   * nested dictionaries, e.g. getManagedProperty(data, 'VPN.Type').
84   * @param {object} data The properties dictionary.
85   * @param {string} key The property key.
86   * @return {*} The property value or dictionary if it exists, otherwise
87   *             undefined.
88   */
89  function getManagedProperty(data, key) {
90    while (true) {
91      var index = key.indexOf('.');
92      if (index < 0)
93        break;
94      var keyComponent = key.substr(0, index);
95      if (!(keyComponent in data))
96        return undefined;
97      data = data[keyComponent];
98      key = key.substr(index + 1);
99    }
100    return data[key];
101  }
102
103  /**
104   * Helper function to set hidden attribute for elements matching a selector.
105   * @param {string} selector CSS selector for extracting a list of elements.
106   * @param {bool} hidden New hidden value.
107   */
108  function updateHidden(selector, hidden) {
109    var elements = cr.doc.querySelectorAll(selector);
110    for (var i = 0, el; el = elements[i]; i++) {
111      el.hidden = hidden;
112    }
113  }
114
115  /*
116   * Helper function to update the properties of the data object from the
117   * properties in the update object.
118   * @param {object} data object to update.
119   * @param {object} object containing the updated properties.
120   */
121  function updateDataObject(data, update) {
122    for (var prop in update) {
123      if (prop in data)
124        data[prop] = update[prop];
125    }
126  }
127
128  /**
129   * Monitor pref change of given element.
130   * @param {Element} el Target element.
131   */
132  function observePrefsUI(el) {
133    Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate);
134  }
135
136  /**
137   * UI pref change handler.
138   * @param {Event} e The update event.
139   */
140  function handlePrefUpdate(e) {
141    DetailsInternetPage.getInstance().updateControls();
142  }
143
144  /**
145   * Simple helper method for converting a field to a string. It is used to
146   * easily assign an empty string from fields that may be unknown or undefined.
147   * @param {object} value that should be converted to a string.
148   * @return {string} the result.
149   */
150  function stringFromValue(value) {
151    return value ? String(value) : '';
152  }
153
154  /**
155   * Sends the 'checked' state of a control to chrome for a network.
156   * @param {string} path The service path of the network.
157   * @param {string} message The message to send to chrome.
158   * @param {HTMLInputElement} checkbox The checkbox storing the value to send.
159   */
160  function sendCheckedIfEnabled(path, message, checkbox) {
161    if (!checkbox.hidden && !checkbox.disabled)
162      chrome.send(message, [path, checkbox.checked ? 'true' : 'false']);
163  }
164
165  /**
166   * Looks up the string to display for 'state' in loadTimeData.
167   * @param {string} state The ONC State property of a network.
168   */
169  function networkOncStateString(state) {
170    if (state == 'NotConnected')
171      return loadTimeData.getString('OncStateNotConnected');
172    else if (state == 'Connecting')
173      return loadTimeData.getString('OncStateConnecting');
174    else if (state == 'Connected')
175      return loadTimeData.getString('OncStateConnected');
176    return loadTimeData.getString('OncStateUnknown');
177  }
178
179  /**
180   * Returns the display name for the network represented by 'data'.
181   * @param {Object} data The network ONC dictionary.
182   */
183  function getNetworkName(data) {
184    if (data.type == 'Ethernet')
185      return loadTimeData.getString('ethernetName');
186    return getManagedValue(data, 'Name');
187  }
188
189  /////////////////////////////////////////////////////////////////////////////
190  // DetailsInternetPage class:
191
192  /**
193   * Encapsulated handling of ChromeOS internet details overlay page.
194   * @constructor
195   */
196  function DetailsInternetPage() {
197    Page.call(this, 'detailsInternetPage', null, 'details-internet-page');
198  }
199
200  cr.addSingletonGetter(DetailsInternetPage);
201
202  DetailsInternetPage.prototype = {
203    __proto__: Page.prototype,
204
205    /** @override */
206    initializePage: function() {
207      Page.prototype.initializePage.call(this);
208      var params = parseQueryParams(window.location);
209      this.initializePageContents_(params);
210      this.showNetworkDetails_(params);
211    },
212
213    /**
214     * Auto-activates the network details dialog if network information
215     * is included in the URL.
216     */
217    showNetworkDetails_: function(params) {
218      var servicePath = params.servicePath;
219      if (!servicePath || !servicePath.length)
220        return;
221      var networkType = '';  // ignored for 'options'
222      chrome.send('networkCommand', [networkType, servicePath, 'options']);
223    },
224
225    /**
226     * Initializes the contents of the page.
227     */
228    initializePageContents_: function(params) {
229      $('details-internet-dismiss').addEventListener('click', function(event) {
230        DetailsInternetPage.setDetails();
231      });
232
233      $('details-internet-login').addEventListener('click', function(event) {
234        DetailsInternetPage.setDetails();
235        DetailsInternetPage.loginFromDetails();
236      });
237
238      $('details-internet-disconnect').addEventListener('click',
239                                                        function(event) {
240        DetailsInternetPage.setDetails();
241        DetailsInternetPage.disconnectNetwork();
242      });
243
244      $('details-internet-configure').addEventListener('click',
245                                                       function(event) {
246        DetailsInternetPage.setDetails();
247        DetailsInternetPage.configureNetwork();
248      });
249
250      $('activate-details').addEventListener('click', function(event) {
251        DetailsInternetPage.activateFromDetails();
252      });
253
254      $('buyplan-details').addEventListener('click', function(event) {
255        var data = $('connection-state').data;
256        chrome.send('buyDataPlan', [data.servicePath]);
257        PageManager.closeOverlay();
258      });
259
260      $('view-account-details').addEventListener('click', function(event) {
261        var data = $('connection-state').data;
262        chrome.send('showMorePlanInfo', [data.servicePath]);
263        PageManager.closeOverlay();
264      });
265
266      $('cellular-apn-use-default').addEventListener('click', function(event) {
267        var data = $('connection-state').data;
268        var apnSelector = $('select-apn');
269
270        if (data.userApnIndex != -1) {
271          apnSelector.remove(data.userApnIndex);
272          data.userApnIndex = -1;
273        }
274
275        if (data.providerApnList.value.length > 0) {
276          var iApn = 0;
277          var defaultApn = data.providerApnList.value[iApn];
278          data.apn.apn = stringFromValue(defaultApn.apn);
279          data.apn.username = stringFromValue(defaultApn.username);
280          data.apn.password = stringFromValue(defaultApn.password);
281          chrome.send('setApn', [data.servicePath,
282                                 data.apn.apn,
283                                 data.apn.username,
284                                 data.apn.password]);
285          apnSelector.selectedIndex = iApn;
286          data.selectedApn = iApn;
287        } else {
288          data.apn.apn = '';
289          data.apn.username = '';
290          data.apn.password = '';
291          apnSelector.selectedIndex = -1;
292          data.selectedApn = -1;
293        }
294        updateHidden('.apn-list-view', false);
295        updateHidden('.apn-details-view', true);
296      });
297
298      $('cellular-apn-set').addEventListener('click', function(event) {
299        if ($('cellular-apn').value == '')
300          return;
301
302        var data = $('connection-state').data;
303        var apnSelector = $('select-apn');
304
305        data.apn.apn = stringFromValue($('cellular-apn').value);
306        data.apn.username = stringFromValue($('cellular-apn-username').value);
307        data.apn.password = stringFromValue($('cellular-apn-password').value);
308        data.userApn = {
309          'apn': data.apn.apn,
310          'username': data.apn.username,
311          'password': data.apn.password
312        };
313        chrome.send('setApn', [data.servicePath,
314                               data.apn.apn,
315                               data.apn.username,
316                               data.apn.password]);
317
318        if (data.userApnIndex != -1) {
319          apnSelector.remove(data.userApnIndex);
320          data.userApnIndex = -1;
321        }
322
323        var option = document.createElement('option');
324        option.textContent = data.apn.apn;
325        option.value = -1;
326        option.selected = true;
327        apnSelector.add(option, apnSelector[apnSelector.length - 1]);
328        data.userApnIndex = apnSelector.length - 2;
329        data.selectedApn = data.userApnIndex;
330
331        updateHidden('.apn-list-view', false);
332        updateHidden('.apn-details-view', true);
333      });
334
335      $('cellular-apn-cancel').addEventListener('click', function(event) {
336        $('select-apn').selectedIndex = $('connection-state').data.selectedApn;
337        updateHidden('.apn-list-view', false);
338        updateHidden('.apn-details-view', true);
339      });
340
341      $('select-apn').addEventListener('change', function(event) {
342        var data = $('connection-state').data;
343        var apnSelector = $('select-apn');
344        if (apnSelector[apnSelector.selectedIndex].value != -1) {
345          var apnList = data.providerApnList.value;
346          chrome.send('setApn', [data.servicePath,
347              stringFromValue(apnList[apnSelector.selectedIndex].apn),
348              stringFromValue(apnList[apnSelector.selectedIndex].username),
349              stringFromValue(apnList[apnSelector.selectedIndex].password)]
350          );
351          data.selectedApn = apnSelector.selectedIndex;
352        } else if (apnSelector.selectedIndex == data.userApnIndex) {
353          chrome.send('setApn', [data.servicePath,
354                                 stringFromValue(data.userApn.apn),
355                                 stringFromValue(data.userApn.username),
356                                 stringFromValue(data.userApn.password)]);
357          data.selectedApn = apnSelector.selectedIndex;
358        } else {
359          $('cellular-apn').value = stringFromValue(data.apn.apn);
360          $('cellular-apn-username').value = stringFromValue(data.apn.username);
361          $('cellular-apn-password').value = stringFromValue(data.apn.password);
362
363          updateHidden('.apn-list-view', true);
364          updateHidden('.apn-details-view', false);
365        }
366      });
367
368      $('sim-card-lock-enabled').addEventListener('click', function(event) {
369        var newValue = $('sim-card-lock-enabled').checked;
370        // Leave value as is because user needs to enter PIN code first.
371        // When PIN will be entered and value changed,
372        // we'll update UI to reflect that change.
373        $('sim-card-lock-enabled').checked = !newValue;
374        chrome.send('setSimCardLock', [newValue]);
375      });
376      $('change-pin').addEventListener('click', function(event) {
377        chrome.send('changePin');
378      });
379
380      // Proxy
381      ['proxy-host-single-port',
382       'secure-proxy-port',
383       'socks-port',
384       'ftp-proxy-port',
385       'proxy-host-port'
386      ].forEach(function(id) {
387        options.PrefPortNumber.decorate($(id));
388      });
389
390      options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list'));
391      $('remove-host').addEventListener('click',
392                                        this.handleRemoveProxyExceptions_);
393      $('add-host').addEventListener('click', this.handleAddProxyException_);
394      $('direct-proxy').addEventListener('click', this.disableManualProxy_);
395      $('manual-proxy').addEventListener('click', this.enableManualProxy_);
396      $('auto-proxy').addEventListener('click', this.disableManualProxy_);
397      $('proxy-all-protocols').addEventListener('click',
398                                                this.toggleSingleProxy_);
399      $('proxy-use-pac-url').addEventListener('change',
400                                              this.handleAutoConfigProxy_);
401
402      observePrefsUI($('direct-proxy'));
403      observePrefsUI($('manual-proxy'));
404      observePrefsUI($('auto-proxy'));
405      observePrefsUI($('proxy-all-protocols'));
406      observePrefsUI($('proxy-use-pac-url'));
407
408      $('ip-automatic-configuration-checkbox').addEventListener('click',
409        this.handleIpAutoConfig_);
410      $('automatic-dns-radio').addEventListener('click',
411        this.handleNameServerTypeChange_);
412      $('google-dns-radio').addEventListener('click',
413        this.handleNameServerTypeChange_);
414      $('user-dns-radio').addEventListener('click',
415        this.handleNameServerTypeChange_);
416
417      // We only load this string if we have the string data available
418      // because the proxy settings page on the login screen re-uses the
419      // proxy sub-page from the internet options, and it doesn't ever
420      // show the DNS settings, so we don't need this string there.
421      // The string isn't available because
422      // chrome://settings-frame/strings.js (where the string is
423      // stored) is not accessible from the login screen.
424      // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login
425      // page is fixed. http://crbug.com/242865
426      if (loadTimeData.data_) {
427        $('google-dns-label').innerHTML =
428          loadTimeData.getString('googleNameServers');
429      }
430    },
431
432    /**
433     * Handler for "add" event fired from userNameEdit.
434     * @param {Event} e Add event fired from userNameEdit.
435     * @private
436     */
437    handleAddProxyException_: function(e) {
438      var exception = $('new-host').value;
439      $('new-host').value = '';
440
441      exception = exception.trim();
442      if (exception)
443        $('ignored-host-list').addException(exception);
444    },
445
446    /**
447     * Handler for when the remove button is clicked
448     * @param {Event} e The click event.
449     * @private
450     */
451    handleRemoveProxyExceptions_: function(e) {
452      var selectedItems = $('ignored-host-list').selectedItems;
453      for (var x = 0; x < selectedItems.length; x++) {
454        $('ignored-host-list').removeException(selectedItems[x]);
455      }
456    },
457
458    /**
459     * Handler for when the IP automatic configuration checkbox is clicked.
460     * @param {Event} e The click event.
461     * @private
462     */
463    handleIpAutoConfig_: function(e) {
464      var checked = $('ip-automatic-configuration-checkbox').checked;
465      var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
466      for (var i = 0; i < fields.length; ++i) {
467        fields[i].editable = !checked;
468        if (checked) {
469          var model = fields[i].model;
470          model.value = model.automatic;
471          fields[i].model = model;
472        }
473      }
474      if (!checked)
475        $('ip-address').focus();
476    },
477
478    /**
479     * Handler for when the name server selection changes.
480     * @param {Event} e The click event.
481     * @private
482     */
483    handleNameServerTypeChange_: function(event) {
484      var type = event.target.value;
485      DetailsInternetPage.updateNameServerDisplay(type);
486    },
487
488    /**
489     * Creates an indicator event for controlled properties using
490     * the same dictionary format as CoreOptionsHandler::CreateValueForPref.
491     * @param {string} name The name for the Event.
492     * @param {Object} data Property dictionary with |value|, |controlledBy|,
493     *  and |recommendedValue| properties set.
494     * @private
495     */
496    createControlledEvent_: function(name, propData) {
497      var event = new Event(name);
498      event.value = {
499        value: propData.value,
500        controlledBy: propData.controlledBy,
501        recommendedValue: propData.recommendedValue
502      };
503      return event;
504    },
505
506    /**
507     * Creates an indicator event for controlled properties using
508     * the ONC getManagedProperties dictionary format.
509     * @param {string} name The name for the Event.
510     * @param {Object} data ONC managed network property dictionary.
511     * @private
512     */
513    createManagedEvent_: function(name, propData) {
514      var event = new Event(name);
515      event.value = {};
516
517      // Set the current value and recommended value.
518      var activeValue = propData['Active'];
519      var effective = propData['Effective'];
520      if (activeValue == undefined)
521        activeValue = propData[effective];
522      event.value.value = activeValue;
523
524      // If a property is editable then it is not enforced, and 'controlledBy'
525      // is set to 'recommended' unless effective == {User|Shared}Setting, in
526      // which case the value was modifed from the recommended value.
527      // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then
528      // the set value is mandated by the policy.
529      if (propData['UserEditable']) {
530        if (effective == 'UserPolicy')
531          event.value.controlledBy = 'recommended';
532        event.value.recommendedValue = propData['UserPolicy'];
533      } else if (propData['DeviceEditable']) {
534        if (effective == 'DevicePolicy')
535          event.value.controlledBy = 'recommended';
536        event.value.recommendedValue = propData['DevicePolicy'];
537      } else if (effective == 'UserPolicy' || effective == 'DevicePolicy') {
538        event.value.controlledBy = 'policy';
539      }
540
541      return event;
542    },
543
544    /**
545     * Update details page controls.
546     */
547    updateControls: function() {
548      // Only show ipconfig section if network is connected OR if nothing on
549      // this device is connected. This is so that you can fix the ip configs
550      // if you can't connect to any network.
551      // TODO(chocobo): Once ipconfig is moved to flimflam service objects,
552      //   we need to redo this logic to allow configuration of all networks.
553      $('ipconfig-section').hidden = !this.connected && this.deviceConnected;
554      $('ipconfig-dns-section').hidden =
555        !this.connected && this.deviceConnected;
556
557      // Network type related.
558      updateHidden('#details-internet-page .cellular-details',
559                   this.type != 'Cellular');
560      updateHidden('#details-internet-page .wifi-details',
561                   this.type != 'WiFi');
562      updateHidden('#details-internet-page .wimax-details',
563                   this.type != 'Wimax');
564      updateHidden('#details-internet-page .vpn-details', this.type != 'VPN');
565      updateHidden('#details-internet-page .proxy-details', !this.showProxy);
566
567      // Cellular
568
569      // Conditionally call updateHidden on .gsm-only, so that we don't unhide
570      // a previously hidden element.
571      if (this.gsm)
572        updateHidden('#details-internet-page .cdma-only', true);
573      else
574        updateHidden('#details-internet-page .gsm-only', true);
575
576      // Wifi
577
578      // Hide network tab for VPN.
579      updateHidden('#details-internet-page .network-details',
580                   this.type == 'VPN');
581
582      // Password and shared.
583      updateHidden('#details-internet-page #password-details',
584                   this.type != 'WiFi' || !this.hasSecurity);
585      updateHidden('#details-internet-page #wifi-shared-network',
586          !this.shared);
587      updateHidden('#details-internet-page #prefer-network',
588                   !this.showPreferred);
589
590      // WiMAX.
591      updateHidden('#details-internet-page #wimax-shared-network',
592                   !this.shared);
593
594      // Proxy
595      this.updateProxyBannerVisibility_();
596      this.toggleSingleProxy_();
597      if ($('manual-proxy').checked)
598        this.enableManualProxy_();
599      else
600        this.disableManualProxy_();
601    },
602
603    /**
604     * Updates info banner visibility state. This function shows the banner
605     * if proxy is managed or shared-proxies is off for shared network.
606     * @private
607     */
608    updateProxyBannerVisibility_: function() {
609      var bannerDiv = $('network-proxy-info-banner');
610      if (!loadTimeData.data_) {
611        // TODO(pneubeck): This temporarily prevents an exception below until
612        // i18n of the proxy dialog on the login page is
613        // fixed. http://crbug.com/242865
614        bannerDiv.hidden = true;
615        return;
616      }
617
618      // Show banner and determine its message if necessary.
619      var controlledBy = $('direct-proxy').controlledBy;
620      if (!controlledBy || controlledBy == '') {
621        bannerDiv.hidden = true;
622      } else {
623        bannerDiv.hidden = false;
624        // The possible banner texts are loaded in proxy_handler.cc.
625        var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() +
626                         controlledBy.slice(1);
627        $('banner-text').textContent = loadTimeData.getString(bannerText);
628      }
629    },
630
631    /**
632     * Handler for when the user clicks on the checkbox to allow a
633     * single proxy usage.
634     * @private
635     * @param {Event} e Click Event.
636     */
637    toggleSingleProxy_: function(e) {
638      if ($('proxy-all-protocols').checked) {
639        $('multi-proxy').hidden = true;
640        $('single-proxy').hidden = false;
641      } else {
642        $('multi-proxy').hidden = false;
643        $('single-proxy').hidden = true;
644      }
645    },
646
647    /**
648     * Handler for when the user clicks on the checkbox to enter
649     * auto configuration URL.
650     * @private
651     * @param {Event} e Click Event.
652     */
653    handleAutoConfigProxy_: function(e) {
654      $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked;
655    },
656
657    /**
658     * Handler for selecting a radio button that will disable the manual
659     * controls.
660     * @private
661     * @param {Event} e Click event.
662     */
663    disableManualProxy_: function(e) {
664      $('ignored-host-list').disabled = true;
665      $('new-host').disabled = true;
666      $('remove-host').disabled = true;
667      $('add-host').disabled = true;
668      $('proxy-all-protocols').disabled = true;
669      $('proxy-host-name').disabled = true;
670      $('proxy-host-port').disabled = true;
671      $('proxy-host-single-name').disabled = true;
672      $('proxy-host-single-port').disabled = true;
673      $('secure-proxy-host-name').disabled = true;
674      $('secure-proxy-port').disabled = true;
675      $('ftp-proxy').disabled = true;
676      $('ftp-proxy-port').disabled = true;
677      $('socks-host').disabled = true;
678      $('socks-port').disabled = true;
679      $('proxy-use-pac-url').disabled = $('auto-proxy').disabled ||
680                                        !$('auto-proxy').checked;
681      $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled ||
682                                    !$('proxy-use-pac-url').checked;
683      $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
684      $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
685      chrome.send('coreOptionsUserMetricsAction',
686                  ['Options_NetworkManualProxy_Disable']);
687    },
688
689    /**
690     * Handler for selecting a radio button that will enable the manual
691     * controls.
692     * @private
693     * @param {Event} e Click event.
694     */
695    enableManualProxy_: function(e) {
696      $('ignored-host-list').redraw();
697      var allDisabled = $('manual-proxy').disabled;
698      $('ignored-host-list').disabled = allDisabled;
699      $('new-host').disabled = allDisabled;
700      $('remove-host').disabled = allDisabled;
701      $('add-host').disabled = allDisabled;
702      $('proxy-all-protocols').disabled = allDisabled;
703      $('proxy-host-name').disabled = allDisabled;
704      $('proxy-host-port').disabled = allDisabled;
705      $('proxy-host-single-name').disabled = allDisabled;
706      $('proxy-host-single-port').disabled = allDisabled;
707      $('secure-proxy-host-name').disabled = allDisabled;
708      $('secure-proxy-port').disabled = allDisabled;
709      $('ftp-proxy').disabled = allDisabled;
710      $('ftp-proxy-port').disabled = allDisabled;
711      $('socks-host').disabled = allDisabled;
712      $('socks-port').disabled = allDisabled;
713      $('proxy-use-pac-url').disabled = true;
714      $('proxy-pac-url').disabled = true;
715      $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
716      $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
717      chrome.send('coreOptionsUserMetricsAction',
718                  ['Options_NetworkManualProxy_Enable']);
719    }
720  };
721
722  /**
723   * Enables or Disables all buttons that provide operations on the cellular
724   * network.
725   */
726  DetailsInternetPage.changeCellularButtonsState = function(disable) {
727    var buttonsToDisableList =
728        new Array('details-internet-login',
729                  'details-internet-disconnect',
730                  'details-internet-configure',
731                  'activate-details',
732                  'buyplan-details',
733                  'view-account-details');
734
735    for (var i = 0; i < buttonsToDisableList.length; ++i) {
736      var button = $(buttonsToDisableList[i]);
737      button.disabled = disable;
738    }
739  };
740
741  /**
742   * Shows a spinner while the carrier is changed.
743   */
744  DetailsInternetPage.showCarrierChangeSpinner = function(visible) {
745    $('switch-carrier-spinner').hidden = !visible;
746    // Disable any buttons that allow us to operate on cellular networks.
747    DetailsInternetPage.changeCellularButtonsState(visible);
748  };
749
750  /**
751   * Changes the network carrier.
752   */
753  DetailsInternetPage.handleCarrierChanged = function() {
754    var carrierSelector = $('select-carrier');
755    var carrier = carrierSelector[carrierSelector.selectedIndex].textContent;
756    DetailsInternetPage.showCarrierChangeSpinner(true);
757    var data = $('connection-state').data;
758    chrome.send('setCarrier', [data.servicePath, carrier]);
759  };
760
761  /**
762   * Performs minimal initialization of the InternetDetails dialog in
763   * preparation for showing proxy-setttings.
764   */
765  DetailsInternetPage.initializeProxySettings = function() {
766    var detailsPage = DetailsInternetPage.getInstance();
767    detailsPage.initializePageContents_();
768  };
769
770  /**
771   * Displays the InternetDetails dialog with only the proxy settings visible.
772   */
773  DetailsInternetPage.showProxySettings = function() {
774    var detailsPage = DetailsInternetPage.getInstance();
775    $('network-details-header').hidden = true;
776    $('buyplan-details').hidden = true;
777    $('activate-details').hidden = true;
778    $('view-account-details').hidden = true;
779    $('web-proxy-auto-discovery').hidden = true;
780    detailsPage.showProxy = true;
781    updateHidden('#internet-tab', true);
782    updateHidden('#details-tab-strip', true);
783    updateHidden('#details-internet-page .action-area', true);
784    detailsPage.updateControls();
785    detailsPage.visible = true;
786    chrome.send('coreOptionsUserMetricsAction',
787                ['Options_NetworkShowProxyTab']);
788  };
789
790  /**
791   * Initializes even handling for keyboard driven flow.
792   */
793  DetailsInternetPage.initializeKeyboardFlow = function() {
794    keyboard.initializeKeyboardFlow();
795  };
796
797  DetailsInternetPage.updateProxySettings = function(type) {
798      var proxyHost = null,
799          proxyPort = null;
800
801      if (type == 'cros.session.proxy.singlehttp') {
802        proxyHost = 'proxy-host-single-name';
803        proxyPort = 'proxy-host-single-port';
804      } else if (type == 'cros.session.proxy.httpurl') {
805        proxyHost = 'proxy-host-name';
806        proxyPort = 'proxy-host-port';
807      } else if (type == 'cros.session.proxy.httpsurl') {
808        proxyHost = 'secure-proxy-host-name';
809        proxyPort = 'secure-proxy-port';
810      } else if (type == 'cros.session.proxy.ftpurl') {
811        proxyHost = 'ftp-proxy';
812        proxyPort = 'ftp-proxy-port';
813      } else if (type == 'cros.session.proxy.socks') {
814        proxyHost = 'socks-host';
815        proxyPort = 'socks-port';
816      } else {
817        return;
818      }
819
820      var hostValue = $(proxyHost).value;
821      if (hostValue.indexOf(':') !== -1) {
822        if (hostValue.match(/:/g).length == 1) {
823          hostValue = hostValue.split(':');
824          $(proxyHost).value = hostValue[0];
825          $(proxyPort).value = hostValue[1];
826        }
827      }
828  };
829
830  DetailsInternetPage.updateCarrier = function() {
831    DetailsInternetPage.showCarrierChangeSpinner(false);
832  };
833
834  DetailsInternetPage.loginFromDetails = function() {
835    var data = $('connection-state').data;
836    var servicePath = data.servicePath;
837    chrome.send('networkCommand', [data.type, servicePath, 'connect']);
838    PageManager.closeOverlay();
839  };
840
841  DetailsInternetPage.disconnectNetwork = function() {
842    var data = $('connection-state').data;
843    var servicePath = data.servicePath;
844    chrome.send('networkCommand', [data.type, servicePath, 'disconnect']);
845    PageManager.closeOverlay();
846  };
847
848  DetailsInternetPage.configureNetwork = function() {
849    var data = $('connection-state').data;
850    var servicePath = data.servicePath;
851    chrome.send('networkCommand', [data.type, servicePath, 'configure']);
852    PageManager.closeOverlay();
853  };
854
855  DetailsInternetPage.activateFromDetails = function() {
856    var data = $('connection-state').data;
857    var servicePath = data.servicePath;
858    if (data.Type == 'Cellular')
859      chrome.send('networkCommand', [data.type, servicePath, 'activate']);
860    PageManager.closeOverlay();
861  };
862
863  DetailsInternetPage.setDetails = function() {
864    var data = $('connection-state').data;
865    var servicePath = data.servicePath;
866    if (data.type == 'WiFi') {
867      sendCheckedIfEnabled(servicePath, 'setPreferNetwork',
868                           $('prefer-network-wifi'));
869      sendCheckedIfEnabled(servicePath, 'setAutoConnect',
870                           $('auto-connect-network-wifi'));
871    } else if (data.type == 'Wimax') {
872      sendCheckedIfEnabled(servicePath, 'setAutoConnect',
873                           $('auto-connect-network-wimax'));
874    } else if (data.type == 'Cellular') {
875      sendCheckedIfEnabled(servicePath, 'setAutoConnect',
876                           $('auto-connect-network-cellular'));
877    } else if (data.type == 'VPN') {
878      chrome.send('setServerHostname',
879                  [servicePath,
880                   $('inet-server-hostname').value]);
881      sendCheckedIfEnabled(servicePath, 'setAutoConnect',
882                           $('auto-connect-network-vpn'));
883    }
884
885    var nameServerTypes = ['automatic', 'google', 'user'];
886    var nameServerType = 'automatic';
887    for (var i = 0; i < nameServerTypes.length; ++i) {
888      if ($(nameServerTypes[i] + '-dns-radio').checked) {
889        nameServerType = nameServerTypes[i];
890        break;
891      }
892    }
893
894    // Skip any empty values.
895    var userNameServers = [];
896    for (var i = 1; i <= 4; ++i) {
897      var nameServerField = $('ipconfig-dns' + i);
898      if (nameServerField && nameServerField.model &&
899          nameServerField.model.value) {
900        userNameServers.push(nameServerField.model.value);
901      }
902    }
903
904    userNameServers = userNameServers.join(',');
905
906    chrome.send('setIPConfig',
907                [servicePath,
908                 Boolean($('ip-automatic-configuration-checkbox').checked),
909                 $('ip-address').model.value || '',
910                 $('ip-netmask').model.value || '',
911                 $('ip-gateway').model.value || '',
912                 nameServerType,
913                 userNameServers]);
914    PageManager.closeOverlay();
915  };
916
917  DetailsInternetPage.updateNameServerDisplay = function(type) {
918    var editable = type == 'user';
919    var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'),
920                  $('ipconfig-dns3'), $('ipconfig-dns4')];
921    for (var i = 0; i < fields.length; ++i) {
922      fields[i].editable = editable;
923    }
924    if (editable)
925      $('ipconfig-dns1').focus();
926
927    var automaticDns = $('automatic-dns-display');
928    var googleDns = $('google-dns-display');
929    var userDns = $('user-dns-settings');
930    switch (type) {
931      case 'automatic':
932        automaticDns.setAttribute('selected', '');
933        googleDns.removeAttribute('selected');
934        userDns.removeAttribute('selected');
935        break;
936      case 'google':
937        automaticDns.removeAttribute('selected');
938        googleDns.setAttribute('selected', '');
939        userDns.removeAttribute('selected');
940        break;
941      case 'user':
942        automaticDns.removeAttribute('selected');
943        googleDns.removeAttribute('selected');
944        userDns.setAttribute('selected', '');
945        break;
946    }
947  };
948
949  DetailsInternetPage.updateConnectionButtonVisibilty = function(data) {
950    if (data.type == 'Ethernet') {
951      // Ethernet can never be connected or disconnected and can always be
952      // configured (e.g. to set security).
953      $('details-internet-login').hidden = true;
954      $('details-internet-disconnect').hidden = true;
955      $('details-internet-configure').hidden = false;
956      return;
957    }
958
959    var connectState = getManagedValue(data, 'ConnectionState');
960    if (connectState == 'NotConnected') {
961      $('details-internet-login').hidden = false;
962      // Connecting to an unconfigured network might trigger certificate
963      // installation UI. Until that gets handled here, always enable the
964      // Connect button.
965      $('details-internet-login').disabled = false;
966      $('details-internet-disconnect').hidden = true;
967    } else {
968      $('details-internet-login').hidden = true;
969      $('details-internet-disconnect').hidden = false;
970    }
971
972    var connectable = getManagedValue(data, 'Connectable');
973    if (connectState != 'Connected' &&
974        (!connectable || this.hasSecurity ||
975        (data.type == 'Wimax' || data.type == 'VPN'))) {
976      $('details-internet-configure').hidden = false;
977    } else {
978      $('details-internet-configure').hidden = true;
979    }
980  };
981
982  DetailsInternetPage.updateConnectionData = function(update) {
983    var detailsPage = DetailsInternetPage.getInstance();
984    if (!detailsPage.visible)
985      return;
986
987    var data = $('connection-state').data;
988    if (!data)
989      return;
990
991    if (update.servicePath != data.servicePath)
992      return;
993
994    // Update our cached data object.
995    updateDataObject(data, update);
996
997    var connectionState = getManagedValue(data, 'ConnectionState');
998    var connectionStateString = networkOncStateString(connectionState);
999    detailsPage.deviceConnected = data.deviceConnected;
1000    detailsPage.connected = connectionState == 'Connected';
1001    $('connection-state').textContent = connectionStateString;
1002
1003    this.updateConnectionButtonVisibilty(data);
1004
1005    if (data.type == 'WiFi') {
1006      $('wifi-connection-state').textContent = connectionStateString;
1007    } else if (data.type == 'Wimax') {
1008      $('wimax-connection-state').textContent = connectionStateString;
1009    } else if (data.type == 'Cellular') {
1010      $('activation-state').textContent = data.activationState;
1011
1012      $('buyplan-details').hidden = !data.showBuyButton;
1013      $('view-account-details').hidden = !data.showViewAccountButton;
1014
1015      $('activate-details').hidden = !data.showActivateButton;
1016      if (data.showActivateButton)
1017        $('details-internet-login').hidden = true;
1018
1019      if (detailsPage.gsm) {
1020        // TODO(stevenjb): Use managed properties for policy controlled values.
1021        var lockEnabled = data.simCardLockEnabled.value;
1022        $('sim-card-lock-enabled').checked = lockEnabled;
1023        $('change-pin').hidden = !lockEnabled;
1024      }
1025    }
1026
1027    $('connection-state').data = data;
1028  };
1029
1030  DetailsInternetPage.showDetailedInfo = function(data) {
1031    var detailsPage = DetailsInternetPage.getInstance();
1032
1033    data.type = getManagedValue(data, 'Type');  // Get Active Type value.
1034
1035    // Populate header
1036    $('network-details-title').textContent = getNetworkName(data);
1037    var connectionState = getManagedValue(data, 'ConnectionState');
1038    var connectionStateString = networkOncStateString(connectionState);
1039    detailsPage.connected = connectionState == 'Connected';
1040    $('network-details-subtitle-status').textContent = connectionStateString;
1041    var typeKey = null;
1042    switch (data.type) {
1043      case 'Ethernet':
1044        typeKey = 'ethernetTitle';
1045        break;
1046      case 'WiFi':
1047        typeKey = 'wifiTitle';
1048        break;
1049      case 'Wimax':
1050        typeKey = 'wimaxTitle';
1051        break;
1052      case 'Cellular':
1053        typeKey = 'cellularTitle';
1054        break;
1055      case 'VPN':
1056        typeKey = 'vpnTitle';
1057        break;
1058    }
1059    var typeLabel = $('network-details-subtitle-type');
1060    var typeSeparator = $('network-details-subtitle-separator');
1061    if (typeKey) {
1062      typeLabel.textContent = loadTimeData.getString(typeKey);
1063      typeLabel.hidden = false;
1064      typeSeparator.hidden = false;
1065    } else {
1066      typeLabel.hidden = true;
1067      typeSeparator.hidden = true;
1068    }
1069
1070    // TODO(stevenjb): Find a more appropriate place to cache data.
1071    $('connection-state').data = data;
1072
1073    $('buyplan-details').hidden = true;
1074    $('activate-details').hidden = true;
1075    $('view-account-details').hidden = true;
1076
1077    this.updateConnectionButtonVisibilty(data);
1078
1079    $('web-proxy-auto-discovery').hidden = true;
1080
1081    detailsPage.deviceConnected = data.deviceConnected;
1082    detailsPage.connected = connectionState == 'Connected';
1083
1084    // Only show proxy for remembered networks.
1085    if (data.remembered) {
1086      detailsPage.showProxy = true;
1087      chrome.send('selectNetwork', [data.servicePath]);
1088    } else {
1089      detailsPage.showProxy = false;
1090    }
1091    $('connection-state').textContent = connectionStateString;
1092
1093    var ipAutoConfig = data.ipAutoConfig ? 'automatic' : 'user';
1094    $('ip-automatic-configuration-checkbox').checked = data.ipAutoConfig;
1095    var inetAddress = {autoConfig: ipAutoConfig};
1096    var inetNetmask = {autoConfig: ipAutoConfig};
1097    var inetGateway = {autoConfig: ipAutoConfig};
1098
1099    if (data.ipconfig.value) {
1100      inetAddress.automatic = data.ipconfig.value.address;
1101      inetAddress.value = data.ipconfig.value.address;
1102      inetNetmask.automatic = data.ipconfig.value.netmask;
1103      inetNetmask.value = data.ipconfig.value.netmask;
1104      inetGateway.automatic = data.ipconfig.value.gateway;
1105      inetGateway.value = data.ipconfig.value.gateway;
1106      if (data.ipconfig.value.webProxyAutoDiscoveryUrl) {
1107        $('web-proxy-auto-discovery').hidden = false;
1108        $('web-proxy-auto-discovery-url').value =
1109            data.ipconfig.value.webProxyAutoDiscoveryUrl;
1110      }
1111    }
1112
1113    // Override the "automatic" values with the real saved DHCP values,
1114    // if they are set.
1115    if (data.savedIP.address) {
1116      inetAddress.automatic = data.savedIP.address;
1117      inetAddress.value = data.savedIP.address;
1118    }
1119    if (data.savedIP.netmask) {
1120      inetNetmask.automatic = data.savedIP.netmask;
1121      inetNetmask.value = data.savedIP.netmask;
1122    }
1123    if (data.savedIP.gateway) {
1124      inetGateway.automatic = data.savedIP.gateway;
1125      inetGateway.value = data.savedIP.gateway;
1126    }
1127
1128    if (ipAutoConfig == 'user') {
1129      if (data.staticIP.value.address) {
1130        inetAddress.value = data.staticIP.value.address;
1131        inetAddress.user = data.staticIP.value.address;
1132      }
1133      if (data.staticIP.value.netmask) {
1134        inetNetmask.value = data.staticIP.value.netmask;
1135        inetNetmask.user = data.staticIP.value.netmask;
1136      }
1137      if (data.staticIP.value.gateway) {
1138        inetGateway.value = data.staticIP.value.gateway;
1139        inetGateway.user = data.staticIP.value.gateway;
1140      }
1141    }
1142
1143    var configureAddressField = function(field, model) {
1144      IPAddressField.decorate(field);
1145      field.model = model;
1146      field.editable = model.autoConfig == 'user';
1147    };
1148
1149    configureAddressField($('ip-address'), inetAddress);
1150    configureAddressField($('ip-netmask'), inetNetmask);
1151    configureAddressField($('ip-gateway'), inetGateway);
1152
1153    var inetNameServers = '';
1154    if (data.ipconfig.value && data.ipconfig.value.nameServers) {
1155      inetNameServers = data.ipconfig.value.nameServers;
1156      $('automatic-dns-display').textContent = inetNameServers;
1157    }
1158
1159    if (data.savedIP && data.savedIP.nameServers)
1160      $('automatic-dns-display').textContent = data.savedIP.nameServers;
1161
1162    if (data.nameServersGoogle)
1163      $('google-dns-display').textContent = data.nameServersGoogle;
1164
1165    var nameServersUser = [];
1166    if (data.staticIP.value.nameServers)
1167      nameServersUser = data.staticIP.value.nameServers.split(',');
1168
1169    var nameServerModels = [];
1170    for (var i = 0; i < 4; ++i)
1171      nameServerModels.push({value: nameServersUser[i] || ''});
1172
1173    $(data.nameServerType + '-dns-radio').checked = true;
1174    configureAddressField($('ipconfig-dns1'), nameServerModels[0]);
1175    configureAddressField($('ipconfig-dns2'), nameServerModels[1]);
1176    configureAddressField($('ipconfig-dns3'), nameServerModels[2]);
1177    configureAddressField($('ipconfig-dns4'), nameServerModels[3]);
1178
1179    DetailsInternetPage.updateNameServerDisplay(data.nameServerType);
1180
1181    var macAddress = getManagedValue(data, 'MacAddress');
1182    if (macAddress) {
1183      $('hardware-address').textContent = macAddress;
1184      $('hardware-address-row').style.display = 'table-row';
1185    } else {
1186      // This is most likely a device without a hardware address.
1187      $('hardware-address-row').style.display = 'none';
1188    }
1189
1190    var setOrHideParent = function(field, property) {
1191      if (property) {
1192        $(field).textContent = property;
1193        $(field).parentElement.hidden = false;
1194      } else {
1195        $(field).parentElement.hidden = true;
1196      }
1197    };
1198
1199    var networkName = getNetworkName(data);
1200
1201    // Signal strength as percentage (for WiFi and Wimax).
1202    var signalStrength;
1203    if (data.type == 'WiFi' || data.type == 'Wimax') {
1204      signalStrength = getManagedValue(data, data.type + '.SignalStrength');
1205    }
1206    if (!signalStrength)
1207      signalStrength = 0;
1208    var strengthFormat = loadTimeData.getString('inetSignalStrengthFormat');
1209    var strengthString = strengthFormat.replace('$1', signalStrength);
1210
1211    detailsPage.type = data.type;
1212    if (data.type == 'WiFi') {
1213      assert('WiFi' in data, 'WiFi network has no WiFi object' + networkName);
1214      OptionsPage.showTab($('wifi-network-nav-tab'));
1215      detailsPage.gsm = false;
1216      detailsPage.shared = data.shared;
1217      $('wifi-connection-state').textContent = connectionStateString;
1218      var ssid = getManagedValue(data, 'WiFi.SSID');
1219      $('wifi-ssid').textContent = ssid ? ssid : networkName;
1220      setOrHideParent('wifi-bssid', getManagedValue(data, 'WiFi.BSSID'));
1221      var security = getManagedValue(data, 'WiFi.Security');
1222      if (security == 'None')
1223        security = undefined;
1224      setOrHideParent('wifi-security', security);
1225      // Frequency is in MHz.
1226      var frequency = getManagedValue(data, 'WiFi.Frequency');
1227      if (!frequency)
1228        frequency = 0;
1229      var frequencyFormat = loadTimeData.getString('inetFrequencyFormat');
1230      frequencyFormat = frequencyFormat.replace('$1', frequency);
1231      $('wifi-frequency').textContent = frequencyFormat;
1232      $('wifi-signal-strength').textContent = strengthString;
1233      setOrHideParent('wifi-hardware-address',
1234                      getManagedValue(data, 'MacAddress'));
1235      detailsPage.showPreferred = data.remembered;
1236      var priority = getManagedValue(data, 'Priority');
1237      $('prefer-network-wifi').checked = priority > 0;
1238      $('prefer-network-wifi').disabled = !data.remembered;
1239      $('auto-connect-network-wifi').checked =
1240          getManagedValue(data, 'AutoConnect');
1241      $('auto-connect-network-wifi').disabled = !data.remembered;
1242      detailsPage.hasSecurity = security != undefined;
1243    } else if (data.type == 'Wimax') {
1244      assert('Wimax' in data,
1245             'Wimax network has no Wimax object' + networkName);
1246      OptionsPage.showTab($('wimax-network-nav-tab'));
1247      detailsPage.gsm = false;
1248      detailsPage.shared = data.shared;
1249      detailsPage.showPreferred = data.remembered;
1250      $('wimax-connection-state').textContent = connectionStateString;
1251      $('auto-connect-network-wimax').checked =
1252          getManagedValue(data, 'AutoConnect');
1253      $('auto-connect-network-wimax').disabled = !data.remembered;
1254      var identity;
1255      if (data.Wimax.EAP)
1256        identity = getManagedValue(data.Wimax.EAP, 'Identity');
1257      setOrHideParent('wimax-eap-identity', identity);
1258      $('wimax-signal-strength').textContent = strengthString;
1259    } else if (data.type == 'Cellular') {
1260      assert('Cellular' in data,
1261             'Cellular network has no Cellular object' + networkName);
1262      OptionsPage.showTab($('cellular-conn-nav-tab'));
1263      if (data.showCarrierSelect && data.currentCarrierIndex != -1) {
1264        var carrierSelector = $('select-carrier');
1265        carrierSelector.onchange = DetailsInternetPage.handleCarrierChanged;
1266        carrierSelector.options.length = 0;
1267        for (var i = 0; i < data.carriers.length; ++i) {
1268          var option = document.createElement('option');
1269          option.textContent = data.carriers[i];
1270          carrierSelector.add(option);
1271        }
1272        carrierSelector.selectedIndex = data.currentCarrierIndex;
1273      } else {
1274        $('service-name').textContent = networkName;
1275      }
1276
1277      $('network-technology').textContent =
1278          getManagedValue(data, 'Cellular.NetworkTechnology');
1279      $('activation-state').textContent = data.activationState;
1280      $('roaming-state').textContent = data.roamingState;
1281      $('restricted-pool').textContent = data.restrictedPool;
1282      $('error-state').textContent = data.errorMessage;
1283      $('manufacturer').textContent =
1284          getManagedValue(data, 'Cellular.Manufacturer');
1285      $('model-id').textContent = getManagedValue(data, 'Cellular.ModelID');
1286      $('firmware-revision').textContent =
1287          getManagedValue(data, 'Cellular.FirmwareRevision');
1288      $('hardware-revision').textContent =
1289          getManagedValue(data, 'Cellular.HardwareRevision');
1290      $('mdn').textContent = getManagedValue(data, 'Cellular.MDN');
1291
1292      // Show ServingOperator properties only if available.
1293      var servingOperatorName =
1294          getManagedValue(data, 'Cellular.ServingOperator.Name');
1295      var servingOperatorCode =
1296          getManagedValue(data, 'Cellular.ServingOperator.Code');
1297      if (servingOperatorName != undefined &&
1298          servingOperatorCode != undefined) {
1299        $('operator-name').textContent = servingOperatorName;
1300        $('operator-code').textContent = servingOperatorCode;
1301      } else {
1302        $('operator-name').parentElement.hidden = true;
1303        $('operator-code').parentElement.hidden = true;
1304      }
1305      // Make sure that GSM/CDMA specific properties that shouldn't be hidden
1306      // are visible.
1307      updateHidden('#details-internet-page .gsm-only', false);
1308      updateHidden('#details-internet-page .cdma-only', false);
1309
1310      // Show IMEI/ESN/MEID/MIN/PRL only if they are available.
1311      setOrHideParent('esn', getManagedValue(data, 'Cellular.ESN'));
1312      setOrHideParent('imei', getManagedValue(data, 'Cellular.IMEI'));
1313      setOrHideParent('meid', getManagedValue(data, 'Cellular.MEID'));
1314      setOrHideParent('min', getManagedValue(data, 'Cellular.MIN'));
1315      setOrHideParent('prl-version',
1316                      getManagedValue(data, 'Cellular.PRLVersion'));
1317
1318      var family = getManagedValue(data, 'Cellular.Family');
1319      detailsPage.gsm = family == 'GSM';
1320      if (detailsPage.gsm) {
1321        $('iccid').textContent = getManagedValue(data, 'Cellular.ICCID');
1322        $('imsi').textContent = getManagedValue(data, 'Cellular.IMSI');
1323
1324        var apnSelector = $('select-apn');
1325        // Clear APN lists, keep only last element that "other".
1326        while (apnSelector.length != 1)
1327          apnSelector.remove(0);
1328        var otherOption = apnSelector[0];
1329        data.selectedApn = -1;
1330        data.userApnIndex = -1;
1331        var apnList = data.providerApnList.value;
1332        for (var i = 0; i < apnList.length; i++) {
1333          var option = document.createElement('option');
1334          var localizedName = apnList[i].localizedName;
1335          var name = localizedName ? localizedName : apnList[i].name;
1336          var apn = apnList[i].apn;
1337          option.textContent = name ? (name + ' (' + apn + ')') : apn;
1338          option.value = i;
1339          // data.apn and data.lastGoodApn will always be defined, however
1340          // data.apn.apn and data.lastGoodApn.apn may not be. This is not a
1341          // problem, as apnList[i].apn will always be defined and the
1342          // comparisons below will work as expected.
1343          if ((data.apn.apn == apn &&
1344               data.apn.username == apnList[i].username &&
1345               data.apn.password == apnList[i].password) ||
1346              (!data.apn.apn &&
1347               data.lastGoodApn.apn == apn &&
1348               data.lastGoodApn.username == apnList[i].username &&
1349               data.lastGoodApn.password == apnList[i].password)) {
1350            data.selectedApn = i;
1351          }
1352          // Insert new option before "other" option.
1353          apnSelector.add(option, otherOption);
1354        }
1355        if (data.selectedApn == -1 && data.apn.apn) {
1356          var option = document.createElement('option');
1357          option.textContent = data.apn.apn;
1358          option.value = -1;
1359          apnSelector.add(option, otherOption);
1360          data.selectedApn = apnSelector.length - 2;
1361          data.userApnIndex = data.selectedApn;
1362        }
1363        apnSelector.selectedIndex = data.selectedApn;
1364        updateHidden('.apn-list-view', false);
1365        updateHidden('.apn-details-view', true);
1366        // TODO(stevenjb): Used managed properties for policy controlled value.
1367        var lockEnabled = data.simCardLockEnabled.value;
1368        $('sim-card-lock-enabled').checked = lockEnabled;
1369        $('change-pin').hidden = !lockEnabled;
1370      }
1371      $('auto-connect-network-cellular').checked =
1372          getManagedValue(data, 'AutoConnect');
1373      $('auto-connect-network-cellular').disabled = false;
1374
1375      $('buyplan-details').hidden = !data.showBuyButton;
1376      $('view-account-details').hidden = !data.showViewAccountButton;
1377      $('activate-details').hidden = !data.showActivateButton;
1378      if (data.showActivateButton) {
1379        $('details-internet-login').hidden = true;
1380      }
1381    } else if (data.type == 'VPN') {
1382      OptionsPage.showTab($('vpn-nav-tab'));
1383      detailsPage.gsm = false;
1384      $('inet-service-name').textContent = networkName;
1385      $('inet-provider-type').textContent =
1386          getManagedValue(data, 'VPN.Type', GetManagedTypes.TRANSLATED);
1387      var providerType =
1388          getManagedValue(data, 'VPN.Type', GetManagedTypes.ACTIVE);
1389      var providerKey = 'VPN.' + providerType;
1390      $('inet-username').textContent =
1391          getManagedValue(data, providerKey + '.Username');
1392      var inetServerHostname = $('inet-server-hostname');
1393      inetServerHostname.value = getManagedValue(data, 'VPN.Host');
1394      inetServerHostname.resetHandler = function() {
1395        PageManager.hideBubble();
1396        var recommended =
1397            getManagedValue(data, 'VPN.Host', GetManagedTypes.RECOMMENDED);
1398        if (recommended != undefined)
1399          inetServerHostname.value = recommended;
1400      };
1401      $('auto-connect-network-vpn').checked =
1402          getManagedValue(data, 'AutoConnect');
1403      $('auto-connect-network-vpn').disabled = false;
1404    } else {
1405      OptionsPage.showTab($('internet-nav-tab'));
1406    }
1407
1408    // Update controlled option indicators.
1409    var indicators = cr.doc.querySelectorAll(
1410        '#details-internet-page .controlled-setting-indicator');
1411    for (var i = 0; i < indicators.length; i++) {
1412      var managed = indicators[i].hasAttribute('managed');
1413      var attributeName = managed ? 'managed' : 'data';
1414      var propName = indicators[i].getAttribute(attributeName);
1415      if (!propName)
1416        continue;
1417      var propValue =
1418          managed ? getManagedProperty(data, propName) : data[propName];
1419      if (propValue == undefined)
1420        continue;
1421      var event;
1422      if (managed)
1423        event = detailsPage.createManagedEvent_(propName, propValue);
1424      else
1425        event = detailsPage.createControlledEvent_(propName, propValue);
1426      indicators[i].handlePrefChange(event);
1427      var forElement = $(indicators[i].getAttribute('for'));
1428      if (forElement) {
1429        if (event.value.controlledBy == 'policy')
1430          forElement.disabled = true;
1431        if (forElement.resetHandler)
1432          indicators[i].resetHandler = forElement.resetHandler;
1433      }
1434    }
1435
1436    detailsPage.updateControls();
1437
1438    // Don't show page name in address bar and in history to prevent people
1439    // navigate here by hand and solve issue with page session restore.
1440    PageManager.showPageByName('detailsInternetPage', false);
1441  };
1442
1443  return {
1444    DetailsInternetPage: DetailsInternetPage
1445  };
1446});
1447