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