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.
5 // require: onc_data.js
7 // NOTE(stevenjb): This code is in the process of being converted to be
8 // compatible with the networkingPrivate extension API:
9 // * The network property dictionaries are being converted to use ONC values.
10 // * chrome.send calls will be replaced with chrome.networkingPrivate calls.
11 // See crbug.com/279351 for more info.
13 cr
.define('options.internet', function() {
14 var OncData
= cr
.onc
.OncData
;
15 var Page
= cr
.ui
.pageManager
.Page
;
16 var PageManager
= cr
.ui
.pageManager
.PageManager
;
17 /** @const */ var IPAddressField
= options
.internet
.IPAddressField
;
19 /** @const */ var GoogleNameServers
= ['8.8.4.4', '8.8.8.8'];
20 /** @const */ var CarrierGenericUMTS
= 'Generic UMTS';
23 * Helper function to set hidden attribute for elements matching a selector.
24 * @param {string} selector CSS selector for extracting a list of elements.
25 * @param {boolean} hidden New hidden value.
27 function updateHidden(selector
, hidden
) {
28 var elements
= cr
.doc
.querySelectorAll(selector
);
29 for (var i
= 0, el
; el
= elements
[i
]; i
++) {
35 * Helper function to update the properties of the data object from the
36 * properties in the update object.
37 * @param {Object} data Object to update.
38 * @param {Object} update Object containing the updated properties.
40 function updateDataObject(data
, update
) {
41 for (var prop
in update
) {
43 data
[prop
] = update
[prop
];
48 * Monitor pref change of given element.
49 * @param {Element} el Target element.
51 function observePrefsUI(el
) {
52 Preferences
.getInstance().addEventListener(el
.pref
, handlePrefUpdate
);
56 * UI pref change handler.
57 * @param {Event} e The update event.
59 function handlePrefUpdate(e
) {
60 DetailsInternetPage
.getInstance().updateControls();
64 * Simple helper method for converting a field to a string. It is used to
65 * easily assign an empty string from fields that may be unknown or undefined.
66 * @param {Object} value that should be converted to a string.
67 * @return {string} the result.
69 function stringFromValue(value
) {
70 return value
? String(value
) : '';
74 * @param {string} action An action to send to coreOptionsUserMetricsAction.
76 function sendChromeMetricsAction(action
) {
77 chrome
.send('coreOptionsUserMetricsAction', [action
]);
81 * Send metrics to Chrome when the detailed page is opened.
82 * @param {string} type The ONC type of the network being shown.
83 * @param {string} state The ONC network state.
85 function sendShowDetailsMetrics(type
, state
) {
87 sendChromeMetricsAction('Options_NetworkShowDetailsWifi');
88 if (state
!= 'NotConnected')
89 sendChromeMetricsAction('Options_NetworkShowDetailsWifiConnected');
90 } else if (type
== 'Cellular') {
91 sendChromeMetricsAction('Options_NetworkShowDetailsCellular');
92 if (state
!= 'NotConnected')
93 sendChromeMetricsAction('Options_NetworkShowDetailsCellularConnected');
94 } else if (type
== 'VPN') {
95 sendChromeMetricsAction('Options_NetworkShowDetailsVPN');
96 if (state
!= 'NotConnected')
97 sendChromeMetricsAction('Options_NetworkShowDetailsVPNConnected');
102 * Returns the netmask as a string for a given prefix length.
103 * @param {number} prefixLength The ONC routing prefix length.
104 * @return {string} The corresponding netmask.
106 function prefixLengthToNetmask(prefixLength
) {
107 // Return the empty string for invalid inputs.
108 if (prefixLength
< 0 || prefixLength
> 32)
111 for (var i
= 0; i
< 4; ++i
) {
113 if (prefixLength
>= 8) {
116 remainder
= prefixLength
;
123 value
= ((2 << (remainder
- 1)) - 1) << (8 - remainder
);
124 netmask
+= value
.toString();
130 * Returns the prefix length from the netmask string.
131 * @param {string} netmask The netmask string, e.g. 255.255.255.0.
132 * @return {number} The corresponding netmask or -1 if invalid.
134 function netmaskToPrefixLength(netmask
) {
135 var prefixLength
= 0;
136 var tokens
= netmask
.split('.');
137 if (tokens
.length
!= 4)
139 for (var i
= 0; i
< tokens
.length
; ++i
) {
140 var token
= tokens
[i
];
141 // If we already found the last mask and the current one is not
142 // '0' then the netmask is invalid. For example, 255.224.255.0
143 if (prefixLength
/ 8 != i
) {
146 } else if (token
== '255') {
148 } else if (token
== '254') {
150 } else if (token
== '252') {
152 } else if (token
== '248') {
154 } else if (token
== '240') {
156 } else if (token
== '224') {
158 } else if (token
== '192') {
160 } else if (token
== '128') {
162 } else if (token
== '0') {
165 // mask is not a valid number.
172 /////////////////////////////////////////////////////////////////////////////
173 // DetailsInternetPage class:
176 * Encapsulated handling of ChromeOS internet details overlay page.
178 * @extends {cr.ui.pageManager.Page}
180 function DetailsInternetPage() {
181 // If non-negative, indicates a custom entry in select-apn.
182 this.userApnIndex_
= -1;
184 // The custom APN properties associated with entry |userApnIndex_|.
187 // The currently selected APN entry in $('select-apn') (which may or may not
188 // == userApnIndex_).
189 this.selectedApnIndex_
= -1;
191 // We show the Proxy configuration tab for remembered networks and when
192 // configuring a proxy from the login screen.
193 this.showProxy_
= false;
195 Page
.call(this, 'detailsInternetPage', '', 'details-internet-page');
198 cr
.addSingletonGetter(DetailsInternetPage
);
200 DetailsInternetPage
.prototype = {
201 __proto__
: Page
.prototype,
204 initializePage: function() {
205 Page
.prototype.initializePage
.call(this);
206 this.initializePageContents_();
207 this.showNetworkDetails_();
211 * Auto-activates the network details dialog if network information
212 * is included in the URL.
214 showNetworkDetails_: function() {
215 var guid
= parseQueryParams(window
.location
).guid
;
216 if (!guid
|| !guid
.length
)
218 chrome
.send('loadVPNProviders');
219 chrome
.networkingPrivate
.getManagedProperties(
220 guid
, DetailsInternetPage
.initializeDetailsPage
);
224 * Initializes the contents of the page.
226 initializePageContents_: function() {
227 $('details-internet-dismiss').addEventListener('click', function(event
) {
228 DetailsInternetPage
.setDetails();
231 $('details-internet-login').addEventListener('click', function(event
) {
232 DetailsInternetPage
.setDetails();
233 DetailsInternetPage
.loginFromDetails();
236 $('details-internet-disconnect').addEventListener('click',
238 DetailsInternetPage
.setDetails();
239 DetailsInternetPage
.disconnectNetwork();
242 $('details-internet-configure').addEventListener('click',
244 DetailsInternetPage
.setDetails();
245 DetailsInternetPage
.configureNetwork();
248 $('activate-details').addEventListener('click', function(event
) {
249 DetailsInternetPage
.activateFromDetails();
252 $('view-account-details').addEventListener('click', function(event
) {
253 chrome
.send('showMorePlanInfo',
254 [DetailsInternetPage
.getInstance().onc_
.guid()]);
255 PageManager
.closeOverlay();
258 $('cellular-apn-use-default').addEventListener('click', function(event
) {
259 DetailsInternetPage
.getInstance().setDefaultApn_();
262 $('cellular-apn-set').addEventListener('click', function(event
) {
263 DetailsInternetPage
.getInstance().setApn_($('cellular-apn').value
);
266 $('cellular-apn-cancel').addEventListener('click', function(event
) {
267 DetailsInternetPage
.getInstance().cancelApn_();
270 $('select-apn').addEventListener('change', function(event
) {
271 DetailsInternetPage
.getInstance().selectApn_();
274 $('sim-card-lock-enabled').addEventListener('click', function(event
) {
275 var newValue
= $('sim-card-lock-enabled').checked
;
276 // Leave value as is because user needs to enter PIN code first.
277 // When PIN will be entered and value changed,
278 // we'll update UI to reflect that change.
279 $('sim-card-lock-enabled').checked
= !newValue
;
280 var operation
= newValue
? 'setLocked' : 'setUnlocked';
281 chrome
.send('simOperation', [operation
]);
283 $('change-pin').addEventListener('click', function(event
) {
284 chrome
.send('simOperation', ['changePin']);
288 ['proxy-host-single-port',
293 ].forEach(function(id
) {
294 options
.PrefPortNumber
.decorate($(id
));
297 options
.proxyexceptions
.ProxyExceptions
.decorate($('ignored-host-list'));
298 $('remove-host').addEventListener('click',
299 this.handleRemoveProxyExceptions_
);
300 $('add-host').addEventListener('click', this.handleAddProxyException_
);
301 $('direct-proxy').addEventListener('click', this.disableManualProxy_
);
302 $('manual-proxy').addEventListener('click', this.enableManualProxy_
);
303 $('auto-proxy').addEventListener('click', this.disableManualProxy_
);
304 $('proxy-all-protocols').addEventListener('click',
305 this.toggleSingleProxy_
);
306 $('proxy-use-pac-url').addEventListener('change',
307 this.handleAutoConfigProxy_
);
309 observePrefsUI($('direct-proxy'));
310 observePrefsUI($('manual-proxy'));
311 observePrefsUI($('auto-proxy'));
312 observePrefsUI($('proxy-all-protocols'));
313 observePrefsUI($('proxy-use-pac-url'));
315 $('ip-automatic-configuration-checkbox').addEventListener('click',
316 this.handleIpAutoConfig_
);
317 $('automatic-dns-radio').addEventListener('click',
318 this.handleNameServerTypeChange_
);
319 $('google-dns-radio').addEventListener('click',
320 this.handleNameServerTypeChange_
);
321 $('user-dns-radio').addEventListener('click',
322 this.handleNameServerTypeChange_
);
324 // We only load this string if we have the string data available
325 // because the proxy settings page on the login screen re-uses the
326 // proxy sub-page from the internet options, and it doesn't ever
327 // show the DNS settings, so we don't need this string there.
328 // The string isn't available because
329 // chrome://settings-frame/strings.js (where the string is
330 // stored) is not accessible from the login screen.
331 // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login
332 // page is fixed. http://crbug.com/242865
333 if (loadTimeData
.data_
) {
334 $('google-dns-label').innerHTML
=
335 loadTimeData
.getString('googleNameServers');
340 * Handler for "add" event fired from userNameEdit.
341 * @param {Event} e Add event fired from userNameEdit.
344 handleAddProxyException_: function(e
) {
345 var exception
= $('new-host').value
;
346 $('new-host').value
= '';
348 exception
= exception
.trim();
350 $('ignored-host-list').addException(exception
);
354 * Handler for when the remove button is clicked
355 * @param {Event} e The click event.
358 handleRemoveProxyExceptions_: function(e
) {
359 var selectedItems
= $('ignored-host-list').selectedItems
;
360 for (var x
= 0; x
< selectedItems
.length
; x
++) {
361 $('ignored-host-list').removeException(selectedItems
[x
]);
366 * Handler for when the IP automatic configuration checkbox is clicked.
367 * @param {Event} e The click event.
370 handleIpAutoConfig_: function(e
) {
371 var checked
= $('ip-automatic-configuration-checkbox').checked
;
372 var fields
= [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
373 for (var i
= 0; i
< fields
.length
; ++i
) {
374 fields
[i
].editable
= !checked
;
376 var model
= fields
[i
].model
;
377 model
.value
= model
.automatic
;
378 fields
[i
].model
= model
;
382 $('ip-address').focus();
386 * Handler for when the name server selection changes.
387 * @param {Event} event The click event.
390 handleNameServerTypeChange_: function(event
) {
391 var type
= event
.target
.value
;
392 DetailsInternetPage
.updateNameServerDisplay(type
);
396 * Gets the IPConfig ONC Object.
397 * @param {string} nameServerType The selected name server type:
398 * 'automatic', 'google', or 'user'.
399 * @return {Object} The IPConfig ONC object.
402 getIpConfig_: function(nameServerType
) {
404 // If 'ip-address' is empty, automatic configuration will be used.
405 if (!$('ip-automatic-configuration-checkbox').checked
&&
406 $('ip-address').model
.value
) {
407 ipConfig
['IPAddress'] = $('ip-address').model
.value
;
408 var netmask
= $('ip-netmask').model
.value
;
409 var routingPrefix
= 0;
411 routingPrefix
= netmaskToPrefixLength(netmask
);
412 if (routingPrefix
== -1) {
413 console
.error('Invalid netmask: ' + netmask
);
417 ipConfig
['RoutingPrefix'] = routingPrefix
;
418 ipConfig
['Gateway'] = $('ip-gateway').model
.value
|| '';
421 // Note: If no nameserver fields are set, automatic configuration will be
422 // used. TODO(stevenjb): Validate input fields.
423 if (nameServerType
!= 'automatic') {
424 var userNameServers
= [];
425 if (nameServerType
== 'google') {
426 userNameServers
= GoogleNameServers
.slice();
427 } else if (nameServerType
== 'user') {
428 for (var i
= 1; i
<= 4; ++i
) {
429 var nameServerField
= $('ipconfig-dns' + i
);
430 // Skip empty values.
431 if (nameServerField
&& nameServerField
.model
&&
432 nameServerField
.model
.value
) {
433 userNameServers
.push(nameServerField
.model
.value
);
437 if (userNameServers
.length
)
438 ipConfig
['NameServers'] = userNameServers
.sort();
444 * Creates an indicator event for controlled properties using
445 * the same dictionary format as CoreOptionsHandler::CreateValueForPref.
446 * @param {string} name The name for the Event.
447 * @param {{value: *, controlledBy: *, recommendedValue: *}} propData
448 * Property dictionary.
451 createControlledEvent_: function(name
, propData
) {
452 assert('value' in propData
&& 'controlledBy' in propData
&&
453 'recommendedValue' in propData
);
454 var event
= new Event(name
);
456 value
: propData
.value
,
457 controlledBy
: propData
.controlledBy
,
458 recommendedValue
: propData
.recommendedValue
464 * Creates an indicator event for controlled properties using
465 * the ONC getManagedProperties dictionary format.
466 * @param {string} name The name for the Event.
467 * @param {Object} propData ONC managed network property dictionary.
470 createManagedEvent_: function(name
, propData
) {
471 var event
= new Event(name
);
474 // Set the current value and recommended value.
475 var activeValue
= propData
['Active'];
476 var effective
= propData
['Effective'];
477 if (activeValue
== undefined)
478 activeValue
= propData
[effective
];
479 event
.value
.value
= activeValue
;
481 // If a property is editable then it is not enforced, and 'controlledBy'
482 // is set to 'recommended' unless effective == {User|Shared}Setting, in
483 // which case the value was modified from the recommended value.
484 // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then
485 // the set value is mandated by the policy.
486 if (propData
['UserEditable']) {
487 if (effective
== 'UserPolicy')
488 event
.value
.controlledBy
= 'recommended';
489 event
.value
.recommendedValue
= propData
['UserPolicy'];
490 } else if (propData
['DeviceEditable']) {
491 if (effective
== 'DevicePolicy')
492 event
.value
.controlledBy
= 'recommended';
493 event
.value
.recommendedValue
= propData
['DevicePolicy'];
494 } else if (effective
== 'UserPolicy' || effective
== 'DevicePolicy') {
495 event
.value
.controlledBy
= 'policy';
502 * Update details page controls.
504 updateControls: function() {
505 // Note: onc may be undefined when called from a pref update before
506 // initialized in initializeDetailsPage.
509 // Always show the ipconfig section. TODO(stevenjb): Improve the display
510 // for unconnected networks. Currently the IP address fields may be
511 // blank if the network is not connected.
512 $('ipconfig-section').hidden
= false;
513 $('ipconfig-dns-section').hidden
= false;
515 // Network type related.
516 updateHidden('#details-internet-page .cellular-details',
517 this.type_
!= 'Cellular');
518 updateHidden('#details-internet-page .wifi-details',
519 this.type_
!= 'WiFi');
520 updateHidden('#details-internet-page .wimax-details',
521 this.type_
!= 'WiMAX');
522 updateHidden('#details-internet-page .vpn-details', this.type_
!= 'VPN');
523 updateHidden('#details-internet-page .proxy-details', !this.showProxy_
);
526 if (onc
&& this.type_
== 'Cellular') {
527 // Hide gsm/cdma specific elements.
528 if (onc
.getActiveValue('Cellular.Family') == 'GSM')
529 updateHidden('#details-internet-page .cdma-only', true);
531 updateHidden('#details-internet-page .gsm-only', true);
536 // Hide network tab for VPN.
537 updateHidden('#details-internet-page .network-details',
538 this.type_
== 'VPN');
540 // Password and shared.
541 var source
= onc
? onc
.getSource() : 'None';
542 var shared
= (source
== 'Device' || source
== 'DevicePolicy');
543 var security
= onc
? onc
.getWiFiSecurity() : 'None';
544 updateHidden('#details-internet-page #password-details',
545 this.type_
!= 'WiFi' || security
== 'None');
546 updateHidden('#details-internet-page #wifi-shared-network', !shared
);
547 updateHidden('#details-internet-page #prefer-network', source
== 'None');
550 updateHidden('#details-internet-page #wimax-shared-network', !shared
);
553 this.updateProxyBannerVisibility_();
554 this.toggleSingleProxy_();
555 if ($('manual-proxy').checked
)
556 this.enableManualProxy_();
558 this.disableManualProxy_();
562 * Updates info banner visibility state. This function shows the banner
563 * if proxy is managed or shared-proxies is off for shared network.
566 updateProxyBannerVisibility_: function() {
567 var bannerDiv
= $('network-proxy-info-banner');
568 if (!loadTimeData
.data_
) {
569 // TODO(pneubeck): This temporarily prevents an exception below until
570 // i18n of the proxy dialog on the login page is
571 // fixed. http://crbug.com/242865
572 bannerDiv
.hidden
= true;
576 // Show banner and determine its message if necessary.
577 var controlledBy
= $('direct-proxy').controlledBy
;
578 if (!controlledBy
|| controlledBy
== '') {
579 bannerDiv
.hidden
= true;
581 bannerDiv
.hidden
= false;
582 // The possible banner texts are loaded in proxy_handler.cc.
583 var bannerText
= 'proxyBanner' + controlledBy
.charAt(0).toUpperCase() +
584 controlledBy
.slice(1);
585 $('banner-text').textContent
= loadTimeData
.getString(bannerText
);
590 * Handler for when the user clicks on the checkbox to allow a
591 * single proxy usage.
594 toggleSingleProxy_: function() {
595 if ($('proxy-all-protocols').checked
) {
596 $('multi-proxy').hidden
= true;
597 $('single-proxy').hidden
= false;
599 $('multi-proxy').hidden
= false;
600 $('single-proxy').hidden
= true;
605 * Handler for when the user clicks on the checkbox to enter
606 * auto configuration URL.
609 handleAutoConfigProxy_: function() {
610 $('proxy-pac-url').disabled
= !$('proxy-use-pac-url').checked
;
614 * Handler for selecting a radio button that will disable the manual
618 disableManualProxy_: function() {
619 $('ignored-host-list').disabled
= true;
620 $('new-host').disabled
= true;
621 $('remove-host').disabled
= true;
622 $('add-host').disabled
= true;
623 $('proxy-all-protocols').disabled
= true;
624 $('proxy-host-name').disabled
= true;
625 $('proxy-host-port').disabled
= true;
626 $('proxy-host-single-name').disabled
= true;
627 $('proxy-host-single-port').disabled
= true;
628 $('secure-proxy-host-name').disabled
= true;
629 $('secure-proxy-port').disabled
= true;
630 $('ftp-proxy').disabled
= true;
631 $('ftp-proxy-port').disabled
= true;
632 $('socks-host').disabled
= true;
633 $('socks-port').disabled
= true;
634 $('proxy-use-pac-url').disabled
= $('auto-proxy').disabled
||
635 !$('auto-proxy').checked
;
636 $('proxy-pac-url').disabled
= $('proxy-use-pac-url').disabled
||
637 !$('proxy-use-pac-url').checked
;
638 $('auto-proxy-parms').hidden
= !$('auto-proxy').checked
;
639 $('manual-proxy-parms').hidden
= !$('manual-proxy').checked
;
640 sendChromeMetricsAction('Options_NetworkManualProxy_Disable');
644 * Handler for selecting a radio button that will enable the manual
648 enableManualProxy_: function() {
649 $('ignored-host-list').redraw();
650 var allDisabled
= $('manual-proxy').disabled
;
651 $('ignored-host-list').disabled
= allDisabled
;
652 $('new-host').disabled
= allDisabled
;
653 $('remove-host').disabled
= allDisabled
;
654 $('add-host').disabled
= allDisabled
;
655 $('proxy-all-protocols').disabled
= allDisabled
;
656 $('proxy-host-name').disabled
= allDisabled
;
657 $('proxy-host-port').disabled
= allDisabled
;
658 $('proxy-host-single-name').disabled
= allDisabled
;
659 $('proxy-host-single-port').disabled
= allDisabled
;
660 $('secure-proxy-host-name').disabled
= allDisabled
;
661 $('secure-proxy-port').disabled
= allDisabled
;
662 $('ftp-proxy').disabled
= allDisabled
;
663 $('ftp-proxy-port').disabled
= allDisabled
;
664 $('socks-host').disabled
= allDisabled
;
665 $('socks-port').disabled
= allDisabled
;
666 $('proxy-use-pac-url').disabled
= true;
667 $('proxy-pac-url').disabled
= true;
668 $('auto-proxy-parms').hidden
= !$('auto-proxy').checked
;
669 $('manual-proxy-parms').hidden
= !$('manual-proxy').checked
;
670 sendChromeMetricsAction('Options_NetworkManualProxy_Enable');
674 * Helper method called from initializeDetailsPage and updateConnectionData.
675 * Updates visibility/enabled of the login/disconnect/configure buttons.
678 updateConnectionButtonVisibilty_: function() {
680 if (this.type_
== 'Ethernet') {
681 // Ethernet can never be connected or disconnected and can always be
682 // configured (e.g. to set security).
683 $('details-internet-login').hidden
= true;
684 $('details-internet-disconnect').hidden
= true;
685 $('details-internet-configure').hidden
= false;
689 var connectState
= onc
.getActiveValue('ConnectionState');
690 if (connectState
== 'NotConnected') {
691 $('details-internet-login').hidden
= false;
692 // Connecting to an unconfigured network might trigger certificate
693 // installation UI. Until that gets handled here, always enable the
695 $('details-internet-login').disabled
= false;
696 $('details-internet-disconnect').hidden
= true;
698 $('details-internet-login').hidden
= true;
699 $('details-internet-disconnect').hidden
= false;
702 var connectable
= onc
.getActiveValue('Connectable');
703 if (connectState
!= 'Connected' &&
704 (!connectable
|| onc
.getWiFiSecurity() != 'None' ||
705 (this.type_
== 'WiMAX' || this.type_
== 'VPN'))) {
706 $('details-internet-configure').hidden
= false;
708 $('details-internet-configure').hidden
= true;
713 * Helper method called from initializeDetailsPage and updateConnectionData.
714 * Updates the connection state property and account / sim card links.
717 updateDetails_: function() {
720 var connectionStateString
= onc
.getTranslatedValue('ConnectionState');
721 $('connection-state').textContent
= connectionStateString
;
723 var type
= this.type_
;
724 var showViewAccount
= false;
725 var showActivate
= false;
726 if (type
== 'WiFi') {
727 $('wifi-connection-state').textContent
= connectionStateString
;
728 } else if (type
== 'WiMAX') {
729 $('wimax-connection-state').textContent
= connectionStateString
;
730 } else if (type
== 'Cellular') {
731 $('activation-state').textContent
=
732 onc
.getTranslatedValue('Cellular.ActivationState');
733 if (onc
.getActiveValue('Cellular.Family') == 'GSM') {
735 onc
.getActiveValue('Cellular.SIMLockStatus.LockEnabled');
736 $('sim-card-lock-enabled').checked
= lockEnabled
;
737 $('change-pin').hidden
= !lockEnabled
;
739 showViewAccount
= onc
.getActiveValue('showViewAccountButton');
740 var activationState
= onc
.getActiveValue('Cellular.ActivationState');
741 showActivate
= activationState
== 'NotActivated' ||
742 activationState
== 'PartiallyActivated';
745 $('view-account-details').hidden
= !showViewAccount
;
746 $('activate-details').hidden
= !showActivate
;
747 // If activation is not complete, hide the login button.
749 $('details-internet-login').hidden
= true;
753 * Helper method called from initializeDetailsPage and updateConnectionData.
754 * Updates the fields in the header section of the details frame.
757 populateHeader_: function() {
760 $('network-details-title').textContent
=
761 this.networkTitle_
|| onc
.getTranslatedValue('Name');
763 var connectionState
= onc
.getActiveValue('ConnectionState');
764 var connectionStateString
= onc
.getTranslatedValue('ConnectionState');
765 $('network-details-subtitle-status').textContent
= connectionStateString
;
768 var type
= this.type_
;
769 if (type
== 'Ethernet')
770 typeKey
= 'ethernetTitle';
771 else if (type
== 'WiFi')
772 typeKey
= 'wifiTitle';
773 else if (type
== 'WiMAX')
774 typeKey
= 'wimaxTitle';
775 else if (type
== 'Cellular')
776 typeKey
= 'cellularTitle';
777 else if (type
== 'VPN')
778 typeKey
= 'vpnTitle';
781 var typeLabel
= $('network-details-subtitle-type');
782 var typeSeparator
= $('network-details-subtitle-separator');
784 typeLabel
.textContent
= loadTimeData
.getString(typeKey
);
785 typeLabel
.hidden
= false;
786 typeSeparator
.hidden
= false;
788 typeLabel
.hidden
= true;
789 typeSeparator
.hidden
= true;
794 * Helper method to insert a 'user' option into the Apn list.
795 * @param {Object} userOption The 'user' apn dictionary
798 insertApnUserOption_: function(userOption
) {
799 // Add the 'user' option before the last option ('other')
800 var apnSelector
= $('select-apn');
801 assert(apnSelector
.length
> 0);
802 var otherOption
= apnSelector
[apnSelector
.length
- 1];
803 apnSelector
.add(userOption
, otherOption
);
804 this.userApnIndex_
= apnSelector
.length
- 2;
805 this.selectedApnIndex_
= this.userApnIndex_
;
809 * Helper method called from initializeApnList to populate the Apn list.
810 * @param {Array} apnList List of available APNs.
813 populateApnList_: function(apnList
) {
815 var apnSelector
= $('select-apn');
816 assert(apnSelector
.length
== 1);
817 var otherOption
= apnSelector
[0];
818 var activeApn
= onc
.getActiveValue('Cellular.APN.AccessPointName');
819 var activeUsername
= onc
.getActiveValue('Cellular.APN.Username');
820 var activePassword
= onc
.getActiveValue('Cellular.APN.Password');
822 onc
.getActiveValue('Cellular.LastGoodAPN.AccessPointName');
823 var lastGoodUsername
=
824 onc
.getActiveValue('Cellular.LastGoodAPN.Username');
825 var lastGoodPassword
=
826 onc
.getActiveValue('Cellular.LastGoodAPN.Password');
827 for (var i
= 0; i
< apnList
.length
; i
++) {
828 var apnDict
= apnList
[i
];
829 var option
= document
.createElement('option');
830 var localizedName
= apnDict
['LocalizedName'];
831 var name
= localizedName
? localizedName
: apnDict
['Name'];
832 var accessPointName
= apnDict
['AccessPointName'];
834 name
? (name
+ ' (' + accessPointName
+ ')') : accessPointName
;
836 // Insert new option before 'other' option.
837 apnSelector
.add(option
, otherOption
);
838 if (this.selectedApnIndex_
!= -1)
840 // If this matches the active Apn name, or LastGoodApn name (or there
841 // is no last good APN), set it as the selected Apn.
842 if ((activeApn
== accessPointName
) ||
843 (!activeApn
&& (!lastGoodApn
|| lastGoodApn
== accessPointName
))) {
844 this.selectedApnIndex_
= i
;
847 if (this.selectedApnIndex_
== -1 && activeApn
) {
848 this.userApn_
= activeApn
;
849 // Create a 'user' entry for any active apn not in the list.
850 var userOption
= document
.createElement('option');
851 userOption
.textContent
= activeApn
;
852 userOption
.value
= -1;
853 this.insertApnUserOption_(userOption
);
858 * Helper method called from initializeDetailsPage to initialize the Apn
862 initializeApnList_: function() {
863 this.selectedApnIndex_
= -1;
864 this.userApnIndex_
= -1;
867 var apnSelector
= $('select-apn');
869 // Clear APN lists, keep only last element, 'other'.
870 while (apnSelector
.length
!= 1)
871 apnSelector
.remove(0);
873 var apnList
= onc
.getActiveValue('Cellular.APNList');
875 // Populate the list with the existing APNs.
876 this.populateApnList_(apnList
);
878 // Create a single 'default' entry.
879 var otherOption
= apnSelector
[0];
880 var defaultOption
= document
.createElement('option');
881 defaultOption
.textContent
=
882 loadTimeData
.getString('cellularApnUseDefault');
883 defaultOption
.value
= -1;
884 // Add 'default' entry before 'other' option
885 apnSelector
.add(defaultOption
, otherOption
);
886 assert(apnSelector
.length
== 2); // 'default', 'other'
887 this.selectedApnIndex_
= 0; // Select 'default'
889 assert(this.selectedApnIndex_
>= 0);
890 apnSelector
.selectedIndex
= this.selectedApnIndex_
;
891 updateHidden('.apn-list-view', false);
892 updateHidden('.apn-details-view', true);
896 * Helper function for setting APN properties.
897 * @param {Object} apnValue Dictionary of APN properties.
900 setActiveApn_: function(apnValue
) {
902 var apnName
= apnValue
['AccessPointName'];
904 activeApn
['AccessPointName'] = apnName
;
905 activeApn
['Username'] = stringFromValue(apnValue
['Username']);
906 activeApn
['Password'] = stringFromValue(apnValue
['Password']);
908 // Set the cached ONC data.
909 this.onc_
.setProperty('Cellular.APN', activeApn
);
910 // Set an ONC object with just the APN values.
911 var oncData
= new OncData({});
912 oncData
.setProperty('Cellular.APN', activeApn
);
913 chrome
.networkingPrivate
.setProperties(this.onc_
.guid(),
918 * Event Listener for the cellular-apn-use-default button.
921 setDefaultApn_: function() {
922 var apnSelector
= $('select-apn');
924 // Remove the 'user' entry if it exists.
925 if (this.userApnIndex_
!= -1) {
926 assert(this.userApnIndex_
< apnSelector
.length
- 1);
927 apnSelector
.remove(this.userApnIndex_
);
928 this.userApnIndex_
= -1;
931 var apnList
= this.onc_
.getActiveValue('Cellular.APNList');
932 var iApn
= (apnList
!= undefined && apnList
.length
> 0) ? 0 : -1;
933 apnSelector
.selectedIndex
= iApn
;
934 this.selectedApnIndex_
= iApn
;
936 // Clear any user APN entry to inform Chrome to use the default APN.
937 this.setActiveApn_({});
939 updateHidden('.apn-list-view', false);
940 updateHidden('.apn-details-view', true);
944 * Event Listener for the cellular-apn-set button.
947 setApn_: function(apnValue
) {
951 var apnSelector
= $('select-apn');
954 activeApn
['AccessPointName'] = stringFromValue(apnValue
);
955 activeApn
['Username'] = stringFromValue($('cellular-apn-username').value
);
956 activeApn
['Password'] = stringFromValue($('cellular-apn-password').value
);
957 this.setActiveApn_(activeApn
);
958 // Set the user selected APN.
959 this.userApn_
= activeApn
;
961 // Remove any existing 'user' entry.
962 if (this.userApnIndex_
!= -1) {
963 assert(this.userApnIndex_
< apnSelector
.length
- 1);
964 apnSelector
.remove(this.userApnIndex_
);
965 this.userApnIndex_
= -1;
968 // Create a new 'user' entry with the new active apn.
969 var option
= document
.createElement('option');
970 option
.textContent
= activeApn
['AccessPointName'];
972 option
.selected
= true;
973 this.insertApnUserOption_(option
);
975 updateHidden('.apn-list-view', false);
976 updateHidden('.apn-details-view', true);
980 * Event Listener for the cellular-apn-cancel button.
983 cancelApn_: function() {
984 this.initializeApnList_();
988 * Event Listener for the select-apn button.
991 selectApn_: function() {
993 var apnSelector
= $('select-apn');
994 if (apnSelector
[apnSelector
.selectedIndex
].value
!= -1) {
995 var apnList
= onc
.getActiveValue('Cellular.APNList');
996 var apnIndex
= apnSelector
.selectedIndex
;
997 assert(apnIndex
< apnList
.length
);
998 this.selectedApnIndex_
= apnIndex
;
999 this.setActiveApn_(apnList
[apnIndex
]);
1000 } else if (apnSelector
.selectedIndex
== this.userApnIndex_
) {
1001 this.selectedApnIndex_
= apnSelector
.selectedIndex
;
1002 this.setActiveApn_(this.userApn_
);
1005 if (this.userApn_
['AccessPointName']) {
1006 // Fill in the details fields with the existing 'user' config.
1007 apnDict
= this.userApn_
;
1009 // No 'user' config, use the current values.
1011 apnDict
['AccessPointName'] =
1012 onc
.getActiveValue('Cellular.APN.AccessPointName');
1013 apnDict
['Username'] = onc
.getActiveValue('Cellular.APN.Username');
1014 apnDict
['Password'] = onc
.getActiveValue('Cellular.APN.Password');
1016 $('cellular-apn').value
= stringFromValue(apnDict
['AccessPointName']);
1017 $('cellular-apn-username').value
= stringFromValue(apnDict
['Username']);
1018 $('cellular-apn-password').value
= stringFromValue(apnDict
['Password']);
1019 updateHidden('.apn-list-view', true);
1020 updateHidden('.apn-details-view', false);
1026 * Enables or Disables all buttons that provide operations on the cellular
1029 DetailsInternetPage
.changeCellularButtonsState = function(disable
) {
1030 var buttonsToDisableList
=
1031 new Array('details-internet-login',
1032 'details-internet-disconnect',
1033 'details-internet-configure',
1035 'view-account-details');
1037 for (var i
= 0; i
< buttonsToDisableList
.length
; ++i
) {
1038 var button
= $(buttonsToDisableList
[i
]);
1039 button
.disabled
= disable
;
1044 * Shows a spinner while the carrier is changed.
1046 DetailsInternetPage
.showCarrierChangeSpinner = function(visible
) {
1047 $('switch-carrier-spinner').hidden
= !visible
;
1048 // Disable any buttons that allow us to operate on cellular networks.
1049 DetailsInternetPage
.changeCellularButtonsState(visible
);
1053 * Changes the network carrier.
1055 DetailsInternetPage
.handleCarrierChanged = function() {
1056 var carrierSelector
= $('select-carrier');
1057 var carrier
= carrierSelector
[carrierSelector
.selectedIndex
].textContent
;
1058 DetailsInternetPage
.showCarrierChangeSpinner(true);
1059 chrome
.send('setCarrier', [carrier
]);
1063 * Performs minimal initialization of the InternetDetails dialog in
1064 * preparation for showing proxy-settings.
1066 DetailsInternetPage
.initializeProxySettings = function() {
1067 DetailsInternetPage
.getInstance().initializePageContents_();
1071 * Displays the InternetDetails dialog with only the proxy settings visible.
1073 DetailsInternetPage
.showProxySettings = function() {
1074 var detailsPage
= DetailsInternetPage
.getInstance();
1075 $('network-details-header').hidden
= true;
1076 $('activate-details').hidden
= true;
1077 $('view-account-details').hidden
= true;
1078 $('web-proxy-auto-discovery').hidden
= true;
1079 detailsPage
.showProxy_
= true;
1080 updateHidden('#internet-tab', true);
1081 updateHidden('#details-tab-strip', true);
1082 updateHidden('#details-internet-page .action-area', true);
1083 detailsPage
.updateControls();
1084 detailsPage
.visible
= true;
1085 sendChromeMetricsAction('Options_NetworkShowProxyTab');
1089 * Initializes even handling for keyboard driven flow.
1091 DetailsInternetPage
.initializeKeyboardFlow = function() {
1092 keyboard
.initializeKeyboardFlow();
1095 DetailsInternetPage
.updateProxySettings = function(type
) {
1096 var proxyHost
= null,
1099 if (type
== 'cros.session.proxy.singlehttp') {
1100 proxyHost
= 'proxy-host-single-name';
1101 proxyPort
= 'proxy-host-single-port';
1102 } else if (type
== 'cros.session.proxy.httpurl') {
1103 proxyHost
= 'proxy-host-name';
1104 proxyPort
= 'proxy-host-port';
1105 } else if (type
== 'cros.session.proxy.httpsurl') {
1106 proxyHost
= 'secure-proxy-host-name';
1107 proxyPort
= 'secure-proxy-port';
1108 } else if (type
== 'cros.session.proxy.ftpurl') {
1109 proxyHost
= 'ftp-proxy';
1110 proxyPort
= 'ftp-proxy-port';
1111 } else if (type
== 'cros.session.proxy.socks') {
1112 proxyHost
= 'socks-host';
1113 proxyPort
= 'socks-port';
1118 var hostValue
= $(proxyHost
).value
;
1119 if (hostValue
.indexOf(':') !== -1) {
1120 if (hostValue
.match(/:/g
).length
== 1) {
1121 hostValue
= hostValue
.split(':');
1122 $(proxyHost
).value
= hostValue
[0];
1123 $(proxyPort
).value
= hostValue
[1];
1128 DetailsInternetPage
.updateCarrier = function() {
1129 DetailsInternetPage
.showCarrierChangeSpinner(false);
1132 DetailsInternetPage
.loginFromDetails = function() {
1133 var detailsPage
= DetailsInternetPage
.getInstance();
1134 if (detailsPage
.type_
== 'WiFi')
1135 sendChromeMetricsAction('Options_NetworkConnectToWifi');
1136 else if (detailsPage
.type_
== 'VPN')
1137 sendChromeMetricsAction('Options_NetworkConnectToVPN');
1138 // TODO(stevenjb): chrome.networkingPrivate.startConnect
1139 chrome
.send('startConnect', [detailsPage
.onc_
.guid()]);
1140 PageManager
.closeOverlay();
1143 DetailsInternetPage
.disconnectNetwork = function() {
1144 var detailsPage
= DetailsInternetPage
.getInstance();
1145 if (detailsPage
.type_
== 'WiFi')
1146 sendChromeMetricsAction('Options_NetworkDisconnectWifi');
1147 else if (detailsPage
.type_
== 'VPN')
1148 sendChromeMetricsAction('Options_NetworkDisconnectVPN');
1149 chrome
.networkingPrivate
.startDisconnect(detailsPage
.onc_
.guid());
1150 PageManager
.closeOverlay();
1153 DetailsInternetPage
.configureNetwork = function() {
1154 var detailsPage
= DetailsInternetPage
.getInstance();
1155 chrome
.send('configureNetwork', [detailsPage
.onc_
.guid()]);
1156 PageManager
.closeOverlay();
1159 DetailsInternetPage
.activateFromDetails = function() {
1160 var detailsPage
= DetailsInternetPage
.getInstance();
1161 if (detailsPage
.type_
== 'Cellular') {
1162 chrome
.send('activateNetwork', [detailsPage
.onc_
.guid()]);
1164 PageManager
.closeOverlay();
1168 * Event handler called when the details page is closed. Sends changed
1169 * properties to Chrome and closes the overlay.
1171 DetailsInternetPage
.setDetails = function() {
1172 var detailsPage
= DetailsInternetPage
.getInstance();
1173 var type
= detailsPage
.type_
;
1174 var oncData
= new OncData({});
1175 var autoConnectCheckboxId
= '';
1176 if (type
== 'WiFi') {
1177 var preferredCheckbox
=
1178 assertInstanceof($('prefer-network-wifi'), HTMLInputElement
);
1179 if (!preferredCheckbox
.hidden
&& !preferredCheckbox
.disabled
) {
1180 var kPreferredPriority
= 1;
1181 var priority
= preferredCheckbox
.checked
? kPreferredPriority
: 0;
1182 oncData
.setProperty('Priority', priority
);
1183 sendChromeMetricsAction('Options_NetworkSetPrefer');
1185 autoConnectCheckboxId
= 'auto-connect-network-wifi';
1186 } else if (type
== 'WiMAX') {
1187 autoConnectCheckboxId
= 'auto-connect-network-wimax';
1188 } else if (type
== 'Cellular') {
1189 autoConnectCheckboxId
= 'auto-connect-network-cellular';
1190 } else if (type
== 'VPN') {
1191 var providerType
= detailsPage
.onc_
.getActiveValue('VPN.Type');
1192 if (providerType
!= 'ThirdPartyVPN') {
1193 oncData
.setProperty('VPN.Type', providerType
);
1194 oncData
.setProperty('VPN.Host', $('inet-server-hostname').value
);
1195 autoConnectCheckboxId
= 'auto-connect-network-vpn';
1198 if (autoConnectCheckboxId
!= '') {
1199 var autoConnectCheckbox
=
1200 assertInstanceof($(autoConnectCheckboxId
), HTMLInputElement
);
1201 if (!autoConnectCheckbox
.hidden
&& !autoConnectCheckbox
.disabled
) {
1202 var autoConnectKey
= type
+ '.AutoConnect';
1203 oncData
.setProperty(autoConnectKey
, !!autoConnectCheckbox
.checked
);
1204 sendChromeMetricsAction('Options_NetworkAutoConnect');
1208 var nameServerTypes
= ['automatic', 'google', 'user'];
1209 var nameServerType
= 'automatic';
1210 for (var i
= 0; i
< nameServerTypes
.length
; ++i
) {
1211 if ($(nameServerTypes
[i
] + '-dns-radio').checked
) {
1212 nameServerType
= nameServerTypes
[i
];
1216 var ipConfig
= detailsPage
.getIpConfig_(nameServerType
);
1217 var ipAddressType
= ('IPAddress' in ipConfig
) ? 'Static' : 'DHCP';
1218 var nameServersType
= ('NameServers' in ipConfig
) ? 'Static' : 'DHCP';
1219 oncData
.setProperty('IPAddressConfigType', ipAddressType
);
1220 oncData
.setProperty('NameServersConfigType', nameServersType
);
1221 oncData
.setProperty('StaticIPConfig', ipConfig
);
1223 var data
= oncData
.getData();
1224 if (Object
.keys(data
).length
> 0) {
1225 // TODO(stevenjb): Only set changed properties.
1226 chrome
.networkingPrivate
.setProperties(detailsPage
.onc_
.guid(), data
);
1229 PageManager
.closeOverlay();
1233 * Event handler called when the name server type changes.
1234 * @param {string} type The selected name sever type, 'automatic', 'google',
1237 DetailsInternetPage
.updateNameServerDisplay = function(type
) {
1238 var editable
= type
== 'user';
1239 var fields
= [$('ipconfig-dns1'), $('ipconfig-dns2'),
1240 $('ipconfig-dns3'), $('ipconfig-dns4')];
1241 for (var i
= 0; i
< fields
.length
; ++i
) {
1242 fields
[i
].editable
= editable
;
1245 $('ipconfig-dns1').focus();
1247 var automaticDns
= $('automatic-dns-display');
1248 var googleDns
= $('google-dns-display');
1249 var userDns
= $('user-dns-settings');
1252 automaticDns
.setAttribute('selected', '');
1253 googleDns
.removeAttribute('selected');
1254 userDns
.removeAttribute('selected');
1257 automaticDns
.removeAttribute('selected');
1258 googleDns
.setAttribute('selected', '');
1259 userDns
.removeAttribute('selected');
1262 automaticDns
.removeAttribute('selected');
1263 googleDns
.removeAttribute('selected');
1264 userDns
.setAttribute('selected', '');
1270 * Method called from Chrome when the ONC properties for the displayed
1271 * network may have changed.
1272 * @param {Object} oncData The updated ONC dictionary for the network.
1274 DetailsInternetPage
.updateConnectionData = function(oncData
) {
1275 var detailsPage
= DetailsInternetPage
.getInstance();
1276 if (!detailsPage
.visible
)
1279 if (oncData
.GUID
!= detailsPage
.onc_
.guid())
1282 // Update our cached data object.
1283 detailsPage
.onc_
= new OncData(oncData
);
1285 detailsPage
.populateHeader_();
1286 detailsPage
.updateConnectionButtonVisibilty_();
1287 detailsPage
.updateDetails_();
1291 * Initializes the details page with the provided ONC data.
1292 * @param {Object} oncData Dictionary of ONC properties.
1294 DetailsInternetPage
.initializeDetailsPage = function(oncData
) {
1295 var onc
= new OncData(oncData
);
1297 var detailsPage
= DetailsInternetPage
.getInstance();
1298 detailsPage
.onc_
= onc
;
1299 var type
= onc
.getActiveValue('Type');
1300 detailsPage
.type_
= type
;
1302 sendShowDetailsMetrics(type
, onc
.getActiveValue('ConnectionState'));
1304 if (type
== 'VPN') {
1305 // Cache the dialog title, which will contain the provider name in the
1306 // case of a third-party VPN provider. This caching is important as the
1307 // provider may go away while the details dialog is being shown, causing
1308 // subsequent updates to be unable to determine the correct title.
1309 detailsPage
.networkTitle_
= options
.VPNProviders
.formatNetworkName(onc
);
1311 delete detailsPage
.networkTitle_
;
1314 detailsPage
.populateHeader_();
1315 detailsPage
.updateConnectionButtonVisibilty_();
1316 detailsPage
.updateDetails_();
1318 // Inform chrome which network to pass events for in InternetOptionsHandler.
1319 chrome
.send('setNetworkGuid', [detailsPage
.onc_
.guid()]);
1321 // TODO(stevenjb): Some of the setup below should be moved to
1322 // updateDetails_() so that updates are reflected in the UI.
1324 // Only show proxy for remembered networks.
1325 var remembered
= onc
.getSource() != 'None';
1327 detailsPage
.showProxy_
= true;
1328 // Inform Chrome which network to use for proxy configuration.
1329 chrome
.send('selectNetwork', [detailsPage
.onc_
.guid()]);
1331 detailsPage
.showProxy_
= false;
1334 $('web-proxy-auto-discovery').hidden
= true;
1336 var restricted
= onc
.getActiveValue('RestrictedConnectivity');
1337 var restrictedString
= loadTimeData
.getString(
1338 restricted
? 'restrictedYes' : 'restrictedNo');
1340 // These objects contain an 'automatic' property that is displayed when
1341 // ip-automatic-configuration-checkbox is checked, and a 'value' property
1342 // that is displayed when unchecked and used to set the associated ONC
1343 // property for StaticIPConfig on commit.
1344 var inetAddress
= {};
1345 var inetNetmask
= {};
1346 var inetGateway
= {};
1348 var inetNameServersString
;
1350 var ipconfigList
= onc
.getActiveValue('IPConfigs');
1351 if (Array
.isArray(ipconfigList
)) {
1352 for (var i
= 0; i
< ipconfigList
.length
; ++i
) {
1353 var ipconfig
= ipconfigList
[i
];
1354 var ipType
= ipconfig
['Type'];
1355 if (ipType
!= 'IPv4') {
1356 // TODO(stevenjb): Handle IPv6 properties.
1359 var address
= ipconfig
['IPAddress'];
1360 inetAddress
.automatic
= address
;
1361 inetAddress
.value
= address
;
1362 var netmask
= prefixLengthToNetmask(ipconfig
['RoutingPrefix']);
1363 inetNetmask
.automatic
= netmask
;
1364 inetNetmask
.value
= netmask
;
1365 var gateway
= ipconfig
['Gateway'];
1366 inetGateway
.automatic
= gateway
;
1367 inetGateway
.value
= gateway
;
1368 if ('WebProxyAutoDiscoveryUrl' in ipconfig
) {
1369 $('web-proxy-auto-discovery').hidden
= false;
1370 $('web-proxy-auto-discovery-url').value
=
1371 ipconfig
['WebProxyAutoDiscoveryUrl'];
1373 if ('NameServers' in ipconfig
) {
1374 var inetNameServers
= ipconfig
['NameServers'];
1375 inetNameServers
= inetNameServers
.sort();
1376 inetNameServersString
= inetNameServers
.join(',');
1378 break; // Use the first IPv4 entry.
1382 // Override the 'automatic' properties with the saved DHCP values if the
1383 // saved value is set, and set any unset 'value' properties.
1384 var savedNameServersString
;
1385 var savedIpAddress
= onc
.getActiveValue('SavedIPConfig.IPAddress');
1386 if (savedIpAddress
!= undefined) {
1387 inetAddress
.automatic
= savedIpAddress
;
1388 if (!inetAddress
.value
)
1389 inetAddress
.value
= savedIpAddress
;
1391 var savedPrefix
= onc
.getActiveValue('SavedIPConfig.RoutingPrefix');
1392 if (savedPrefix
!= undefined) {
1393 assert(typeof savedPrefix
== 'number');
1394 var savedNetmask
= prefixLengthToNetmask(
1395 /** @type {number} */(savedPrefix
));
1396 inetNetmask
.automatic
= savedNetmask
;
1397 if (!inetNetmask
.value
)
1398 inetNetmask
.value
= savedNetmask
;
1400 var savedGateway
= onc
.getActiveValue('SavedIPConfig.Gateway');
1401 if (savedGateway
!= undefined) {
1402 inetGateway
.automatic
= savedGateway
;
1403 if (!inetGateway
.value
)
1404 inetGateway
.value
= savedGateway
;
1407 var savedNameServers
= onc
.getActiveValue('SavedIPConfig.NameServers');
1408 if (savedNameServers
) {
1409 savedNameServers
= savedNameServers
.sort();
1410 savedNameServersString
= savedNameServers
.join(',');
1413 var ipAutoConfig
= 'automatic';
1414 if (onc
.getActiveValue('IPAddressConfigType') == 'Static') {
1415 ipAutoConfig
= 'user';
1416 var staticIpAddress
= onc
.getActiveValue('StaticIPConfig.IPAddress');
1417 inetAddress
.user
= staticIpAddress
;
1418 inetAddress
.value
= staticIpAddress
;
1420 var staticPrefix
= onc
.getActiveValue('StaticIPConfig.RoutingPrefix');
1421 if (typeof staticPrefix
!= 'number')
1423 var staticNetmask
= prefixLengthToNetmask(
1424 /** @type {number} */ (staticPrefix
));
1425 inetNetmask
.user
= staticNetmask
;
1426 inetNetmask
.value
= staticNetmask
;
1428 var staticGateway
= onc
.getActiveValue('StaticIPConfig.Gateway');
1429 inetGateway
.user
= staticGateway
;
1430 inetGateway
.value
= staticGateway
;
1433 var staticNameServersString
;
1434 if (onc
.getActiveValue('NameServersConfigType') == 'Static') {
1435 var staticNameServers
= onc
.getActiveValue('StaticIPConfig.NameServers');
1436 staticNameServers
= staticNameServers
.sort();
1437 staticNameServersString
= staticNameServers
.join(',');
1440 $('ip-automatic-configuration-checkbox').checked
=
1441 ipAutoConfig
== 'automatic';
1443 inetAddress
.autoConfig
= ipAutoConfig
;
1444 inetNetmask
.autoConfig
= ipAutoConfig
;
1445 inetGateway
.autoConfig
= ipAutoConfig
;
1447 var configureAddressField = function(field
, model
) {
1448 IPAddressField
.decorate(field
);
1449 field
.model
= model
;
1450 field
.editable
= model
.autoConfig
== 'user';
1452 configureAddressField($('ip-address'), inetAddress
);
1453 configureAddressField($('ip-netmask'), inetNetmask
);
1454 configureAddressField($('ip-gateway'), inetGateway
);
1456 // Set Nameserver fields. Nameservers are 'automatic' by default. If a
1457 // static namerserver is set, use that unless it does not match a non
1458 // empty 'NameServers' value (indicating that the custom nameservers are
1459 // invalid or not being applied for some reason). TODO(stevenjb): Only
1460 // set these properites if they change so that invalid custom values do
1462 var nameServerType
= 'automatic';
1463 if (staticNameServersString
&&
1464 (!inetNameServersString
||
1465 staticNameServersString
== inetNameServersString
)) {
1466 if (staticNameServersString
== GoogleNameServers
.join(','))
1467 nameServerType
= 'google';
1469 nameServerType
= 'user';
1471 if (nameServerType
== 'automatic')
1472 $('automatic-dns-display').textContent
= inetNameServersString
;
1474 $('automatic-dns-display').textContent
= savedNameServersString
;
1475 $('google-dns-display').textContent
= GoogleNameServers
.join(',');
1477 var nameServersUser
= [];
1478 if (staticNameServers
) {
1479 nameServersUser
= staticNameServers
;
1480 } else if (savedNameServers
) {
1481 // Pre-populate with values provided by DHCP server.
1482 nameServersUser
= savedNameServers
;
1485 var nameServerModels
= [];
1486 for (var i
= 0; i
< 4; ++i
)
1487 nameServerModels
.push({value
: nameServersUser
[i
] || ''});
1489 $(nameServerType
+ '-dns-radio').checked
= true;
1490 configureAddressField($('ipconfig-dns1'), nameServerModels
[0]);
1491 configureAddressField($('ipconfig-dns2'), nameServerModels
[1]);
1492 configureAddressField($('ipconfig-dns3'), nameServerModels
[2]);
1493 configureAddressField($('ipconfig-dns4'), nameServerModels
[3]);
1495 DetailsInternetPage
.updateNameServerDisplay(nameServerType
);
1497 var macAddress
= onc
.getActiveValue('MacAddress');
1499 $('hardware-address').textContent
= macAddress
;
1500 $('hardware-address-row').style
.display
= 'table-row';
1502 // This is most likely a device without a hardware address.
1503 $('hardware-address-row').style
.display
= 'none';
1506 var setOrHideParent = function(field
, property
) {
1507 if (property
!= undefined) {
1508 $(field
).textContent
= property
;
1509 $(field
).parentElement
.hidden
= false;
1511 $(field
).parentElement
.hidden
= true;
1515 var networkName
= onc
.getTranslatedValue('Name');
1517 // Signal strength as percentage (for WiFi and WiMAX).
1519 if (type
== 'WiFi' || type
== 'WiMAX')
1520 signalStrength
= onc
.getActiveValue(type
+ '.SignalStrength');
1521 if (!signalStrength
)
1523 var strengthFormat
= loadTimeData
.getString('inetSignalStrengthFormat');
1524 var strengthString
= strengthFormat
.replace('$1', signalStrength
);
1526 if (type
== 'WiFi') {
1527 OptionsPage
.showTab($('wifi-network-nav-tab'));
1528 $('wifi-restricted-connectivity').textContent
= restrictedString
;
1529 var ssid
= onc
.getActiveValue('WiFi.SSID');
1530 $('wifi-ssid').textContent
= ssid
? ssid
: networkName
;
1531 setOrHideParent('wifi-bssid', onc
.getActiveValue('WiFi.BSSID'));
1532 var security
= onc
.getWiFiSecurity();
1533 if (security
== 'None')
1534 security
= undefined;
1535 setOrHideParent('wifi-security', security
);
1536 // Frequency is in MHz.
1537 var frequency
= onc
.getActiveValue('WiFi.Frequency');
1540 var frequencyFormat
= loadTimeData
.getString('inetFrequencyFormat');
1541 frequencyFormat
= frequencyFormat
.replace('$1', frequency
);
1542 $('wifi-frequency').textContent
= frequencyFormat
;
1543 $('wifi-signal-strength').textContent
= strengthString
;
1544 setOrHideParent('wifi-hardware-address',
1545 onc
.getActiveValue('MacAddress'));
1546 var priority
= onc
.getActiveValue('Priority');
1547 $('prefer-network-wifi').checked
= priority
> 0;
1548 $('prefer-network-wifi').disabled
= !remembered
;
1549 $('auto-connect-network-wifi').checked
=
1550 onc
.getActiveValue('WiFi.AutoConnect');
1551 $('auto-connect-network-wifi').disabled
= !remembered
;
1552 } else if (type
== 'WiMAX') {
1553 OptionsPage
.showTab($('wimax-network-nav-tab'));
1554 $('wimax-restricted-connectivity').textContent
= restrictedString
;
1556 $('auto-connect-network-wimax').checked
=
1557 onc
.getActiveValue('WiMAX.AutoConnect');
1558 $('auto-connect-network-wimax').disabled
= !remembered
;
1559 var identity
= onc
.getActiveValue('WiMAX.EAP.Identity');
1560 setOrHideParent('wimax-eap-identity', identity
);
1561 $('wimax-signal-strength').textContent
= strengthString
;
1562 } else if (type
== 'Cellular') {
1563 OptionsPage
.showTab($('cellular-conn-nav-tab'));
1565 var isGsm
= onc
.getActiveValue('Cellular.Family') == 'GSM';
1567 var currentCarrierIndex
= -1;
1568 if (loadTimeData
.getValue('showCarrierSelect')) {
1569 var currentCarrier
=
1570 isGsm
? CarrierGenericUMTS
: onc
.getActiveValue('Cellular.Carrier');
1571 var supportedCarriers
=
1572 onc
.getActiveValue('Cellular.SupportedCarriers');
1573 for (var c1
= 0; c1
< supportedCarriers
.length
; ++c1
) {
1574 if (supportedCarriers
[c1
] == currentCarrier
) {
1575 currentCarrierIndex
= c1
;
1579 if (currentCarrierIndex
!= -1) {
1580 var carrierSelector
= $('select-carrier');
1581 carrierSelector
.onchange
= DetailsInternetPage
.handleCarrierChanged
;
1582 carrierSelector
.options
.length
= 0;
1583 for (var c2
= 0; c2
< supportedCarriers
.length
; ++c2
) {
1584 var option
= document
.createElement('option');
1585 option
.textContent
= supportedCarriers
[c2
];
1586 carrierSelector
.add(option
);
1588 carrierSelector
.selectedIndex
= currentCarrierIndex
;
1591 if (currentCarrierIndex
== -1)
1592 $('service-name').textContent
= networkName
;
1594 // TODO(stevenjb): Ideally many of these should be localized.
1595 $('network-technology').textContent
=
1596 onc
.getActiveValue('Cellular.NetworkTechnology');
1597 $('roaming-state').textContent
=
1598 onc
.getTranslatedValue('Cellular.RoamingState');
1599 $('cellular-restricted-connectivity').textContent
= restrictedString
;
1600 $('error-state').textContent
= onc
.getActiveValue('ErrorState');
1601 $('manufacturer').textContent
=
1602 onc
.getActiveValue('Cellular.Manufacturer');
1603 $('model-id').textContent
= onc
.getActiveValue('Cellular.ModelID');
1604 $('firmware-revision').textContent
=
1605 onc
.getActiveValue('Cellular.FirmwareRevision');
1606 $('hardware-revision').textContent
=
1607 onc
.getActiveValue('Cellular.HardwareRevision');
1608 $('mdn').textContent
= onc
.getActiveValue('Cellular.MDN');
1610 // Show ServingOperator properties only if available.
1611 var servingOperatorName
=
1612 onc
.getActiveValue('Cellular.ServingOperator.Name');
1613 var servingOperatorCode
=
1614 onc
.getActiveValue('Cellular.ServingOperator.Code');
1615 if (servingOperatorName
!= undefined &&
1616 servingOperatorCode
!= undefined) {
1617 $('operator-name').textContent
= servingOperatorName
;
1618 $('operator-code').textContent
= servingOperatorCode
;
1620 $('operator-name').parentElement
.hidden
= true;
1621 $('operator-code').parentElement
.hidden
= true;
1623 // Make sure that GSM/CDMA specific properties that shouldn't be hidden
1625 updateHidden('#details-internet-page .gsm-only', false);
1626 updateHidden('#details-internet-page .cdma-only', false);
1628 // Show IMEI/ESN/MEID/MIN/PRL only if they are available.
1629 setOrHideParent('esn', onc
.getActiveValue('Cellular.ESN'));
1630 setOrHideParent('imei', onc
.getActiveValue('Cellular.IMEI'));
1631 setOrHideParent('meid', onc
.getActiveValue('Cellular.MEID'));
1632 setOrHideParent('min', onc
.getActiveValue('Cellular.MIN'));
1633 setOrHideParent('prl-version', onc
.getActiveValue('Cellular.PRLVersion'));
1636 $('iccid').textContent
= onc
.getActiveValue('Cellular.ICCID');
1637 $('imsi').textContent
= onc
.getActiveValue('Cellular.IMSI');
1638 detailsPage
.initializeApnList_();
1640 $('auto-connect-network-cellular').checked
=
1641 onc
.getActiveValue('Cellular.AutoConnect');
1642 $('auto-connect-network-cellular').disabled
= false;
1643 } else if (type
== 'VPN') {
1644 OptionsPage
.showTab($('vpn-nav-tab'));
1645 var providerType
= onc
.getActiveValue('VPN.Type');
1646 var isThirdPartyVPN
= providerType
== 'ThirdPartyVPN';
1647 $('vpn-tab').classList
.toggle('third-party-vpn-provider',
1650 $('inet-service-name').textContent
= networkName
;
1651 $('inet-provider-type').textContent
=
1652 onc
.getTranslatedValue('VPN.Type');
1654 if (isThirdPartyVPN
) {
1655 $('inet-provider-name').textContent
= '';
1656 var extensionID
= onc
.getActiveValue('VPN.ThirdPartyVPN.ExtensionID');
1657 var providers
= options
.VPNProviders
.getProviders();
1658 for (var i
= 0; i
< providers
.length
; ++i
) {
1659 if (extensionID
== providers
[i
].extensionID
) {
1660 $('inet-provider-name').textContent
= providers
[i
].name
;
1666 if (providerType
== 'OpenVPN')
1667 usernameKey
= 'VPN.OpenVPN.Username';
1668 else if (providerType
== 'L2TP-IPsec')
1669 usernameKey
= 'VPN.L2TP.Username';
1672 $('inet-username').parentElement
.hidden
= false;
1673 $('inet-username').textContent
= onc
.getActiveValue(usernameKey
);
1675 $('inet-username').parentElement
.hidden
= true;
1677 var inetServerHostname
= $('inet-server-hostname');
1678 inetServerHostname
.value
= onc
.getActiveValue('VPN.Host');
1679 inetServerHostname
.resetHandler = function() {
1680 PageManager
.hideBubble();
1681 var recommended
= onc
.getRecommendedValue('VPN.Host');
1682 if (recommended
!= undefined)
1683 inetServerHostname
.value
= recommended
;
1685 $('auto-connect-network-vpn').checked
=
1686 onc
.getActiveValue('VPN.AutoConnect');
1687 $('auto-connect-network-vpn').disabled
= false;
1690 OptionsPage
.showTab($('internet-nav-tab'));
1693 // Update controlled option indicators.
1694 var indicators
= cr
.doc
.querySelectorAll(
1695 '#details-internet-page .controlled-setting-indicator');
1696 for (var i
= 0; i
< indicators
.length
; i
++) {
1697 var managed
= indicators
[i
].hasAttribute('managed');
1698 // TODO(stevenjb): Eliminate support for 'data' once 39 is stable.
1699 var attributeName
= managed
? 'managed' : 'data';
1700 var propName
= indicators
[i
].getAttribute(attributeName
);
1703 var propValue
= managed
?
1704 onc
.getManagedProperty(propName
) :
1705 onc
.getActiveValue(propName
);
1706 // If the property is unset or unmanaged (i.e. not an Object) skip it.
1707 if (propValue
== undefined || (typeof propValue
!= 'object'))
1711 event
= detailsPage
.createManagedEvent_(propName
, propValue
);
1713 event
= detailsPage
.createControlledEvent_(propName
,
1714 /** @type {{value: *, controlledBy: *, recommendedValue: *}} */(
1716 indicators
[i
].handlePrefChange(event
);
1717 var forElement
= $(indicators
[i
].getAttribute('internet-detail-for'));
1719 if (event
.value
.controlledBy
== 'policy')
1720 forElement
.disabled
= true;
1721 if (forElement
.resetHandler
)
1722 indicators
[i
].resetHandler
= forElement
.resetHandler
;
1726 detailsPage
.updateControls();
1728 // Don't show page name in address bar and in history to prevent people
1729 // navigate here by hand and solve issue with page session restore.
1730 PageManager
.showPageByName('detailsInternetPage', false);
1734 DetailsInternetPage
: DetailsInternetPage