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 CarrierSprint
= 'Sprint';
21 /** @const */ var CarrierVerizon
= 'Verizon Wireless';
24 * Helper function to set hidden attribute for elements matching a selector.
25 * @param {string} selector CSS selector for extracting a list of elements.
26 * @param {boolean} hidden New hidden value.
28 function updateHidden(selector
, hidden
) {
29 var elements
= cr
.doc
.querySelectorAll(selector
);
30 for (var i
= 0, el
; el
= elements
[i
]; i
++) {
36 * Helper function to update the properties of the data object from the
37 * properties in the update object.
38 * @param {Object} data Object to update.
39 * @param {Object} update Object containing the updated properties.
41 function updateDataObject(data
, update
) {
42 for (var prop
in update
) {
44 data
[prop
] = update
[prop
];
49 * Monitor pref change of given element.
50 * @param {Element} el Target element.
52 function observePrefsUI(el
) {
53 Preferences
.getInstance().addEventListener(el
.pref
, handlePrefUpdate
);
57 * UI pref change handler.
58 * @param {Event} e The update event.
60 function handlePrefUpdate(e
) {
61 DetailsInternetPage
.getInstance().updateControls();
65 * Simple helper method for converting a field to a string. It is used to
66 * easily assign an empty string from fields that may be unknown or undefined.
67 * @param {Object} value that should be converted to a string.
68 * @return {string} the result.
70 function stringFromValue(value
) {
71 return value
? String(value
) : '';
75 * @param {string} action An action to send to coreOptionsUserMetricsAction.
77 function sendChromeMetricsAction(action
) {
78 chrome
.send('coreOptionsUserMetricsAction', [action
]);
82 * Send metrics to Chrome when the detailed page is opened.
83 * @param {string} type The ONC type of the network being shown.
84 * @param {string} state The ONC network state.
86 function sendShowDetailsMetrics(type
, state
) {
88 sendChromeMetricsAction('Options_NetworkShowDetailsWifi');
89 if (state
!= 'NotConnected')
90 sendChromeMetricsAction('Options_NetworkShowDetailsWifiConnected');
91 } else if (type
== 'Cellular') {
92 sendChromeMetricsAction('Options_NetworkShowDetailsCellular');
93 if (state
!= 'NotConnected')
94 sendChromeMetricsAction('Options_NetworkShowDetailsCellularConnected');
95 } else if (type
== 'VPN') {
96 sendChromeMetricsAction('Options_NetworkShowDetailsVPN');
97 if (state
!= 'NotConnected')
98 sendChromeMetricsAction('Options_NetworkShowDetailsVPNConnected');
103 * Returns the netmask as a string for a given prefix length.
104 * @param {number} prefixLength The ONC routing prefix length.
105 * @return {string} The corresponding netmask.
107 function prefixLengthToNetmask(prefixLength
) {
108 // Return the empty string for invalid inputs.
109 if (prefixLength
< 0 || prefixLength
> 32)
112 for (var i
= 0; i
< 4; ++i
) {
114 if (prefixLength
>= 8) {
117 remainder
= prefixLength
;
124 value
= ((2 << (remainder
- 1)) - 1) << (8 - remainder
);
125 netmask
+= value
.toString();
131 * Returns the prefix length from the netmask string.
132 * @param {string} netmask The netmask string, e.g. 255.255.255.0.
133 * @return {number} The corresponding netmask or -1 if invalid.
135 function netmaskToPrefixLength(netmask
) {
136 var prefixLength
= 0;
137 var tokens
= netmask
.split('.');
138 if (tokens
.length
!= 4)
140 for (var i
= 0; i
< tokens
.length
; ++i
) {
141 var token
= tokens
[i
];
142 // If we already found the last mask and the current one is not
143 // '0' then the netmask is invalid. For example, 255.224.255.0
144 if (prefixLength
/ 8 != i
) {
147 } else if (token
== '255') {
149 } else if (token
== '254') {
151 } else if (token
== '252') {
153 } else if (token
== '248') {
155 } else if (token
== '240') {
157 } else if (token
== '224') {
159 } else if (token
== '192') {
161 } else if (token
== '128') {
163 } else if (token
== '0') {
166 // mask is not a valid number.
173 // Returns true if we should show the 'View Account' button for |onc|.
174 // TODO(stevenjb): We should query the Mobile Config API for whether or not to
175 // show the 'View Account' button once it is integrated with Settings.
176 function shouldShowViewAccountButton(onc
) {
177 var activationState
= onc
.getActiveValue('Cellular.ActivationState');
178 if (activationState
!= 'Activating' && activationState
!= 'Activated')
181 // If no online payment URL was provided by Shill, only show 'View Account'
182 // for Verizon Wireless.
183 if (!onc
.getActiveValue('Cellular.PaymentPortal.Url') &&
184 onc
.getActiveValue('Cellular.Carrier') != CarrierVerizon
) {
188 // 'View Account' should only be shown for connected networks, or
189 // disconnected LTE networks with a valid MDN.
190 var connectionState
= onc
.getActiveValue('ConnectionState');
191 if (connectionState
!= 'Connected') {
192 var technology
= onc
.getActiveValue('Cellular.NetworkTechnology');
193 if (technology
!= 'LTE' && technology
!= 'LTEAdvanced')
195 if (!onc
.getActiveValue('Cellular.MDN'))
202 /////////////////////////////////////////////////////////////////////////////
203 // DetailsInternetPage class:
206 * Encapsulated handling of ChromeOS internet details overlay page.
208 * @extends {cr.ui.pageManager.Page}
210 function DetailsInternetPage() {
211 // If non-negative, indicates a custom entry in select-apn.
212 this.userApnIndex_
= -1;
214 // The custom APN properties associated with entry |userApnIndex_|.
217 // The currently selected APN entry in $('select-apn') (which may or may not
218 // == userApnIndex_).
219 this.selectedApnIndex_
= -1;
221 // We show the Proxy configuration tab for remembered networks and when
222 // configuring a proxy from the login screen.
223 this.showProxy_
= false;
225 Page
.call(this, 'detailsInternetPage', '', 'details-internet-page');
228 cr
.addSingletonGetter(DetailsInternetPage
);
230 DetailsInternetPage
.prototype = {
231 __proto__
: Page
.prototype,
234 initializePage: function() {
235 Page
.prototype.initializePage
.call(this);
236 this.initializePageContents_();
238 chrome
.networkingPrivate
.onNetworksChanged
.addListener(
239 this.onNetworksChanged_
.bind(this));
241 this.showNetworkDetails_();
245 * Automatically shows the network details dialog if network information
246 * is included in the URL.
248 showNetworkDetails_: function() {
249 var guid
= parseQueryParams(window
.location
).guid
;
250 if (!guid
|| !guid
.length
)
252 chrome
.send('loadVPNProviders');
253 chrome
.networkingPrivate
.getManagedProperties(
254 guid
, DetailsInternetPage
.initializeDetailsPage
);
258 * networkingPrivate callback when networks change.
259 * @param {Array<string>} changes List of GUIDs whose properties have
263 onNetworksChanged_: function(changes
) {
266 var guid
= this.onc_
.guid();
267 if (changes
.indexOf(guid
) != -1) {
268 chrome
.networkingPrivate
.getManagedProperties(
269 guid
, DetailsInternetPage
.updateConnectionData
);
274 * Initializes the contents of the page.
276 initializePageContents_: function() {
277 $('details-internet-dismiss').addEventListener('click', function(event
) {
278 DetailsInternetPage
.setDetails();
281 $('details-internet-login').addEventListener('click', function(event
) {
282 DetailsInternetPage
.setDetails();
283 DetailsInternetPage
.loginFromDetails();
286 $('details-internet-disconnect').addEventListener('click',
288 DetailsInternetPage
.setDetails();
289 DetailsInternetPage
.disconnectNetwork();
292 $('details-internet-configure').addEventListener('click',
294 DetailsInternetPage
.setDetails();
295 DetailsInternetPage
.configureNetwork();
298 $('activate-details').addEventListener('click', function(event
) {
299 DetailsInternetPage
.activateFromDetails();
302 $('view-account-details').addEventListener('click', function(event
) {
303 chrome
.send('showMorePlanInfo',
304 [DetailsInternetPage
.getInstance().onc_
.guid()]);
305 PageManager
.closeOverlay();
308 $('cellular-apn-use-default').addEventListener('click', function(event
) {
309 DetailsInternetPage
.getInstance().setDefaultApn_();
312 $('cellular-apn-set').addEventListener('click', function(event
) {
313 DetailsInternetPage
.getInstance().setApn_($('cellular-apn').value
);
316 $('cellular-apn-cancel').addEventListener('click', function(event
) {
317 DetailsInternetPage
.getInstance().cancelApn_();
320 $('select-apn').addEventListener('change', function(event
) {
321 DetailsInternetPage
.getInstance().selectApn_();
324 $('sim-card-lock-enabled').addEventListener('click', function(event
) {
325 var newValue
= $('sim-card-lock-enabled').checked
;
326 // Leave value as is because user needs to enter PIN code first.
327 // When PIN will be entered and value changed,
328 // we'll update UI to reflect that change.
329 $('sim-card-lock-enabled').checked
= !newValue
;
330 var operation
= newValue
? 'setLocked' : 'setUnlocked';
331 chrome
.send('simOperation', [operation
]);
333 $('change-pin').addEventListener('click', function(event
) {
334 chrome
.send('simOperation', ['changePin']);
338 ['proxy-host-single-port',
343 ].forEach(function(id
) {
344 options
.PrefPortNumber
.decorate($(id
));
347 options
.proxyexceptions
.ProxyExceptions
.decorate($('ignored-host-list'));
348 $('remove-host').addEventListener('click',
349 this.handleRemoveProxyExceptions_
);
350 $('add-host').addEventListener('click', this.handleAddProxyException_
);
351 $('direct-proxy').addEventListener('click', this.disableManualProxy_
);
352 $('manual-proxy').addEventListener('click', this.enableManualProxy_
);
353 $('auto-proxy').addEventListener('click', this.disableManualProxy_
);
354 $('proxy-all-protocols').addEventListener('click',
355 this.toggleSingleProxy_
);
356 $('proxy-use-pac-url').addEventListener('change',
357 this.handleAutoConfigProxy_
);
359 observePrefsUI($('direct-proxy'));
360 observePrefsUI($('manual-proxy'));
361 observePrefsUI($('auto-proxy'));
362 observePrefsUI($('proxy-all-protocols'));
363 observePrefsUI($('proxy-use-pac-url'));
365 $('ip-automatic-configuration-checkbox').addEventListener('click',
366 this.handleIpAutoConfig_
);
367 $('automatic-dns-radio').addEventListener('click',
368 this.handleNameServerTypeChange_
);
369 $('google-dns-radio').addEventListener('click',
370 this.handleNameServerTypeChange_
);
371 $('user-dns-radio').addEventListener('click',
372 this.handleNameServerTypeChange_
);
374 // We only load this string if we have the string data available
375 // because the proxy settings page on the login screen re-uses the
376 // proxy sub-page from the internet options, and it doesn't ever
377 // show the DNS settings, so we don't need this string there.
378 // The string isn't available because
379 // chrome://settings-frame/strings.js (where the string is
380 // stored) is not accessible from the login screen.
381 // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login
382 // page is fixed. http://crbug.com/242865
383 if (loadTimeData
.data_
) {
384 $('google-dns-label').innerHTML
=
385 loadTimeData
.getString('googleNameServers');
390 * Handler for "add" event fired from userNameEdit.
391 * @param {Event} e Add event fired from userNameEdit.
394 handleAddProxyException_: function(e
) {
395 var exception
= $('new-host').value
;
396 $('new-host').value
= '';
398 exception
= exception
.trim();
400 $('ignored-host-list').addException(exception
);
404 * Handler for when the remove button is clicked
405 * @param {Event} e The click event.
408 handleRemoveProxyExceptions_: function(e
) {
409 var selectedItems
= $('ignored-host-list').selectedItems
;
410 for (var x
= 0; x
< selectedItems
.length
; x
++) {
411 $('ignored-host-list').removeException(selectedItems
[x
]);
416 * Handler for when the IP automatic configuration checkbox is clicked.
417 * @param {Event} e The click event.
420 handleIpAutoConfig_: function(e
) {
421 var checked
= $('ip-automatic-configuration-checkbox').checked
;
422 var fields
= [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
423 for (var i
= 0; i
< fields
.length
; ++i
) {
424 fields
[i
].editable
= !checked
;
426 var model
= fields
[i
].model
;
427 model
.value
= model
.automatic
;
428 fields
[i
].model
= model
;
432 $('ip-address').focus();
436 * Handler for when the name server selection changes.
437 * @param {Event} event The click event.
440 handleNameServerTypeChange_: function(event
) {
441 var type
= event
.target
.value
;
442 DetailsInternetPage
.updateNameServerDisplay(type
);
446 * Gets the IPConfig ONC Object.
447 * @param {string} nameServerType The selected name server type:
448 * 'automatic', 'google', or 'user'.
449 * @return {Object} The IPConfig ONC object.
452 getIpConfig_: function(nameServerType
) {
454 // If 'ip-address' is empty, automatic configuration will be used.
455 if (!$('ip-automatic-configuration-checkbox').checked
&&
456 $('ip-address').model
.value
) {
457 ipConfig
['IPAddress'] = $('ip-address').model
.value
;
458 var netmask
= $('ip-netmask').model
.value
;
459 var routingPrefix
= 0;
461 routingPrefix
= netmaskToPrefixLength(netmask
);
462 if (routingPrefix
== -1) {
463 console
.error('Invalid netmask: ' + netmask
);
467 ipConfig
['RoutingPrefix'] = routingPrefix
;
468 ipConfig
['Gateway'] = $('ip-gateway').model
.value
|| '';
471 // Note: If no nameserver fields are set, automatic configuration will be
472 // used. TODO(stevenjb): Validate input fields.
473 if (nameServerType
!= 'automatic') {
474 var userNameServers
= [];
475 if (nameServerType
== 'google') {
476 userNameServers
= GoogleNameServers
.slice();
477 } else if (nameServerType
== 'user') {
478 for (var i
= 1; i
<= 4; ++i
) {
479 var nameServerField
= $('ipconfig-dns' + i
);
480 // Skip empty values.
481 if (nameServerField
&& nameServerField
.model
&&
482 nameServerField
.model
.value
) {
483 userNameServers
.push(nameServerField
.model
.value
);
487 if (userNameServers
.length
)
488 ipConfig
['NameServers'] = userNameServers
.sort();
494 * Creates an indicator event for controlled properties using
495 * the same dictionary format as CoreOptionsHandler::CreateValueForPref.
496 * @param {string} name The name for the Event.
497 * @param {{value: *, controlledBy: *, recommendedValue: *}} propData
498 * Property dictionary.
501 createControlledEvent_: function(name
, propData
) {
502 assert('value' in propData
&& 'controlledBy' in propData
&&
503 'recommendedValue' in propData
);
504 var event
= new Event(name
);
506 value
: propData
.value
,
507 controlledBy
: propData
.controlledBy
,
508 recommendedValue
: propData
.recommendedValue
514 * Creates an indicator event for controlled properties using
515 * the ONC getManagedProperties dictionary format.
516 * @param {string} name The name for the Event.
517 * @param {Object} propData ONC managed network property dictionary.
520 createManagedEvent_: function(name
, propData
) {
521 var event
= new Event(name
);
524 // Set the current value and recommended value.
525 var activeValue
= propData
['Active'];
526 var effective
= propData
['Effective'];
527 if (activeValue
== undefined)
528 activeValue
= propData
[effective
];
529 event
.value
.value
= activeValue
;
531 // If a property is editable then it is not enforced, and 'controlledBy'
532 // is set to 'recommended' unless effective == {User|Shared}Setting, in
533 // which case the value was modified from the recommended value.
534 // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then
535 // the set value is mandated by the policy.
536 if (propData
['UserEditable']) {
537 if (effective
== 'UserPolicy')
538 event
.value
.controlledBy
= 'recommended';
539 event
.value
.recommendedValue
= propData
['UserPolicy'];
540 } else if (propData
['DeviceEditable']) {
541 if (effective
== 'DevicePolicy')
542 event
.value
.controlledBy
= 'recommended';
543 event
.value
.recommendedValue
= propData
['DevicePolicy'];
544 } else if (effective
== 'UserPolicy' || effective
== 'DevicePolicy') {
545 event
.value
.controlledBy
= 'policy';
552 * Update details page controls.
554 updateControls: function() {
555 // Note: onc may be undefined when called from a pref update before
556 // initialized in initializeDetailsPage.
559 // Always show the ipconfig section. TODO(stevenjb): Improve the display
560 // for unconnected networks. Currently the IP address fields may be
561 // blank if the network is not connected.
562 $('ipconfig-section').hidden
= false;
563 $('ipconfig-dns-section').hidden
= false;
565 // Network type related.
566 updateHidden('#details-internet-page .cellular-details',
567 this.type_
!= 'Cellular');
568 updateHidden('#details-internet-page .wifi-details',
569 this.type_
!= 'WiFi');
570 updateHidden('#details-internet-page .wimax-details',
571 this.type_
!= 'WiMAX');
572 updateHidden('#details-internet-page .vpn-details', this.type_
!= 'VPN');
573 updateHidden('#details-internet-page .proxy-details', !this.showProxy_
);
576 if (onc
&& this.type_
== 'Cellular') {
577 // Hide gsm/cdma specific elements.
578 if (onc
.getActiveValue('Cellular.Family') == 'GSM')
579 updateHidden('#details-internet-page .cdma-only', true);
581 updateHidden('#details-internet-page .gsm-only', true);
586 // Hide network tab for VPN.
587 updateHidden('#details-internet-page .network-details',
588 this.type_
== 'VPN');
590 // Password and shared.
591 var source
= onc
? onc
.getSource() : 'None';
592 var shared
= (source
== 'Device' || source
== 'DevicePolicy');
593 var security
= onc
? onc
.getWiFiSecurity() : 'None';
594 updateHidden('#details-internet-page #password-details',
595 this.type_
!= 'WiFi' || security
== 'None');
596 updateHidden('#details-internet-page #wifi-shared-network', !shared
);
597 updateHidden('#details-internet-page #prefer-network', source
== 'None');
600 updateHidden('#details-internet-page #wimax-shared-network', !shared
);
603 this.updateProxyBannerVisibility_();
604 this.toggleSingleProxy_();
605 if ($('manual-proxy').checked
)
606 this.enableManualProxy_();
608 this.disableManualProxy_();
612 * Updates info banner visibility state. This function shows the banner
613 * if proxy is managed or shared-proxies is off for shared network.
616 updateProxyBannerVisibility_: function() {
617 var bannerDiv
= $('network-proxy-info-banner');
618 if (!loadTimeData
.data_
) {
619 // TODO(pneubeck): This temporarily prevents an exception below until
620 // i18n of the proxy dialog on the login page is
621 // fixed. http://crbug.com/242865
622 bannerDiv
.hidden
= true;
626 // Show banner and determine its message if necessary.
627 var controlledBy
= $('direct-proxy').controlledBy
;
628 if (!controlledBy
|| controlledBy
== '') {
629 bannerDiv
.hidden
= true;
631 bannerDiv
.hidden
= false;
632 // The possible banner texts are loaded in proxy_handler.cc.
633 var bannerText
= 'proxyBanner' + controlledBy
.charAt(0).toUpperCase() +
634 controlledBy
.slice(1);
635 $('banner-text').textContent
= loadTimeData
.getString(bannerText
);
640 * Handler for when the user clicks on the checkbox to allow a
641 * single proxy usage.
644 toggleSingleProxy_: function() {
645 if ($('proxy-all-protocols').checked
) {
646 $('multi-proxy').hidden
= true;
647 $('single-proxy').hidden
= false;
649 $('multi-proxy').hidden
= false;
650 $('single-proxy').hidden
= true;
655 * Handler for when the user clicks on the checkbox to enter
656 * auto configuration URL.
659 handleAutoConfigProxy_: function() {
660 $('proxy-pac-url').disabled
= !$('proxy-use-pac-url').checked
;
664 * Handler for selecting a radio button that will disable the manual
668 disableManualProxy_: function() {
669 $('ignored-host-list').disabled
= true;
670 $('new-host').disabled
= true;
671 $('remove-host').disabled
= true;
672 $('add-host').disabled
= true;
673 $('proxy-all-protocols').disabled
= true;
674 $('proxy-host-name').disabled
= true;
675 $('proxy-host-port').disabled
= true;
676 $('proxy-host-single-name').disabled
= true;
677 $('proxy-host-single-port').disabled
= true;
678 $('secure-proxy-host-name').disabled
= true;
679 $('secure-proxy-port').disabled
= true;
680 $('ftp-proxy').disabled
= true;
681 $('ftp-proxy-port').disabled
= true;
682 $('socks-host').disabled
= true;
683 $('socks-port').disabled
= true;
684 $('proxy-use-pac-url').disabled
= $('auto-proxy').disabled
||
685 !$('auto-proxy').checked
;
686 $('proxy-pac-url').disabled
= $('proxy-use-pac-url').disabled
||
687 !$('proxy-use-pac-url').checked
;
688 $('auto-proxy-parms').hidden
= !$('auto-proxy').checked
;
689 $('manual-proxy-parms').hidden
= !$('manual-proxy').checked
;
690 sendChromeMetricsAction('Options_NetworkManualProxy_Disable');
694 * Handler for selecting a radio button that will enable the manual
698 enableManualProxy_: function() {
699 $('ignored-host-list').redraw();
700 var allDisabled
= $('manual-proxy').disabled
;
701 $('ignored-host-list').disabled
= allDisabled
;
702 $('new-host').disabled
= allDisabled
;
703 $('remove-host').disabled
= allDisabled
;
704 $('add-host').disabled
= allDisabled
;
705 $('proxy-all-protocols').disabled
= allDisabled
;
706 $('proxy-host-name').disabled
= allDisabled
;
707 $('proxy-host-port').disabled
= allDisabled
;
708 $('proxy-host-single-name').disabled
= allDisabled
;
709 $('proxy-host-single-port').disabled
= allDisabled
;
710 $('secure-proxy-host-name').disabled
= allDisabled
;
711 $('secure-proxy-port').disabled
= allDisabled
;
712 $('ftp-proxy').disabled
= allDisabled
;
713 $('ftp-proxy-port').disabled
= allDisabled
;
714 $('socks-host').disabled
= allDisabled
;
715 $('socks-port').disabled
= allDisabled
;
716 $('proxy-use-pac-url').disabled
= true;
717 $('proxy-pac-url').disabled
= true;
718 $('auto-proxy-parms').hidden
= !$('auto-proxy').checked
;
719 $('manual-proxy-parms').hidden
= !$('manual-proxy').checked
;
720 sendChromeMetricsAction('Options_NetworkManualProxy_Enable');
724 * Helper method called from initializeDetailsPage and updateConnectionData.
725 * Updates visibility/enabled of the login/disconnect/configure buttons.
728 updateConnectionButtonVisibilty_: function() {
730 if (this.type_
== 'Ethernet') {
731 // Ethernet can never be connected or disconnected and can always be
732 // configured (e.g. to set security).
733 $('details-internet-login').hidden
= true;
734 $('details-internet-disconnect').hidden
= true;
735 $('details-internet-configure').hidden
= false;
739 var connectable
= onc
.getActiveValue('Connectable');
740 var connectState
= onc
.getActiveValue('ConnectionState');
741 if (connectState
== 'NotConnected') {
742 $('details-internet-disconnect').hidden
= true;
743 $('details-internet-login').hidden
= false;
744 // Connecting to an unconfigured network might trigger certificate
745 // installation UI. Until that gets handled here, always enable the
746 // Connect button for built-in networks.
747 var enabled
= (this.type_
!= 'VPN') ||
748 (onc
.getActiveValue('VPN.Type') != 'ThirdPartyVPN') ||
750 $('details-internet-login').disabled
= !enabled
;
752 $('details-internet-login').hidden
= true;
753 $('details-internet-disconnect').hidden
= false;
756 var showConfigure
= false;
757 if (this.type_
== 'VPN') {
758 showConfigure
= true;
759 } else if (this.type_
== 'WiMAX' && connectState
== 'NotConnected') {
760 showConfigure
= true;
761 } else if (this.type_
== 'WiFi') {
762 showConfigure
= (connectState
== 'NotConnected' &&
763 (!connectable
|| onc
.getWiFiSecurity() != 'None'));
765 $('details-internet-configure').hidden
= !showConfigure
;
769 * Helper method called from initializeDetailsPage and updateConnectionData.
770 * Updates the connection state property and account / sim card links.
773 updateDetails_: function() {
776 var connectionStateString
= onc
.getTranslatedValue('ConnectionState');
777 $('connection-state').textContent
= connectionStateString
;
779 var type
= this.type_
;
780 var showViewAccount
= false;
781 var showActivate
= false;
782 if (type
== 'WiFi') {
783 $('wifi-connection-state').textContent
= connectionStateString
;
784 } else if (type
== 'WiMAX') {
785 $('wimax-connection-state').textContent
= connectionStateString
;
786 } else if (type
== 'Cellular') {
787 $('activation-state').textContent
=
788 onc
.getTranslatedValue('Cellular.ActivationState');
789 if (onc
.getActiveValue('Cellular.Family') == 'GSM') {
791 onc
.getActiveValue('Cellular.SIMLockStatus.LockEnabled');
792 $('sim-card-lock-enabled').checked
= lockEnabled
;
793 $('change-pin').hidden
= !lockEnabled
;
795 showViewAccount
= shouldShowViewAccountButton(onc
);
796 var activationState
= onc
.getActiveValue('Cellular.ActivationState');
797 showActivate
= (activationState
== 'NotActivated' ||
798 activationState
== 'PartiallyActivated');
801 $('view-account-details').hidden
= !showViewAccount
;
802 $('activate-details').hidden
= !showActivate
;
803 // If activation is not complete, hide the login button.
805 $('details-internet-login').hidden
= true;
809 * Helper method called from initializeDetailsPage and updateConnectionData.
810 * Updates the fields in the header section of the details frame.
813 populateHeader_: function() {
816 $('network-details-title').textContent
=
817 this.networkTitle_
|| onc
.getTranslatedValue('Name');
819 var connectionStateString
= onc
.getTranslatedValue('ConnectionState');
820 $('network-details-subtitle-status').textContent
= connectionStateString
;
823 var type
= this.type_
;
824 if (type
== 'Ethernet')
825 typeKey
= 'ethernetTitle';
826 else if (type
== 'WiFi')
827 typeKey
= 'wifiTitle';
828 else if (type
== 'WiMAX')
829 typeKey
= 'wimaxTitle';
830 else if (type
== 'Cellular')
831 typeKey
= 'cellularTitle';
832 else if (type
== 'VPN')
833 typeKey
= 'vpnTitle';
836 var typeLabel
= $('network-details-subtitle-type');
837 var typeSeparator
= $('network-details-subtitle-separator');
839 typeLabel
.textContent
= loadTimeData
.getString(typeKey
);
840 typeLabel
.hidden
= false;
841 typeSeparator
.hidden
= false;
843 typeLabel
.hidden
= true;
844 typeSeparator
.hidden
= true;
849 * Helper method to insert a 'user' option into the Apn list.
850 * @param {Object} userOption The 'user' apn dictionary
853 insertApnUserOption_: function(userOption
) {
854 // Add the 'user' option before the last option ('other')
855 var apnSelector
= $('select-apn');
856 assert(apnSelector
.length
> 0);
857 var otherOption
= apnSelector
[apnSelector
.length
- 1];
858 apnSelector
.add(userOption
, otherOption
);
859 this.userApnIndex_
= apnSelector
.length
- 2;
860 this.selectedApnIndex_
= this.userApnIndex_
;
864 * Helper method called from initializeApnList to populate the Apn list.
865 * @param {Array} apnList List of available APNs.
868 populateApnList_: function(apnList
) {
870 var apnSelector
= $('select-apn');
871 assert(apnSelector
.length
== 1);
872 var otherOption
= apnSelector
[0];
873 var activeApn
= onc
.getActiveValue('Cellular.APN.AccessPointName');
875 onc
.getActiveValue('Cellular.LastGoodAPN.AccessPointName');
876 for (var i
= 0; i
< apnList
.length
; i
++) {
877 var apnDict
= apnList
[i
];
878 var localizedName
= apnDict
['LocalizedName'];
879 var name
= localizedName
? localizedName
: apnDict
['Name'];
880 var accessPointName
= apnDict
['AccessPointName'];
881 var option
= document
.createElement('option');
883 name
? (name
+ ' (' + accessPointName
+ ')') : accessPointName
;
885 // Insert new option before 'other' option.
886 apnSelector
.add(option
, otherOption
);
887 if (this.selectedApnIndex_
!= -1)
889 // If this matches the active Apn name, or LastGoodApn name (or there
890 // is no last good APN), set it as the selected Apn.
891 if ((activeApn
== accessPointName
) ||
892 (!activeApn
&& (!lastGoodApn
|| lastGoodApn
== accessPointName
))) {
893 this.selectedApnIndex_
= i
;
896 if (this.selectedApnIndex_
== -1 && activeApn
) {
897 this.userApn_
= activeApn
;
898 // Create a 'user' entry for any active apn not in the list.
899 var userOption
= document
.createElement('option');
900 userOption
.textContent
= activeApn
;
901 userOption
.value
= -1;
902 this.insertApnUserOption_(userOption
);
907 * Helper method called from initializeDetailsPage to initialize the Apn
911 initializeApnList_: function() {
912 this.selectedApnIndex_
= -1;
913 this.userApnIndex_
= -1;
916 var apnSelector
= $('select-apn');
918 // Clear APN lists, keep only last element, 'other'.
919 while (apnSelector
.length
!= 1)
920 apnSelector
.remove(0);
922 var apnList
= onc
.getActiveValue('Cellular.APNList');
924 // Populate the list with the existing APNs.
925 this.populateApnList_(apnList
);
927 // Create a single 'default' entry.
928 var otherOption
= apnSelector
[0];
929 var defaultOption
= document
.createElement('option');
930 defaultOption
.textContent
=
931 loadTimeData
.getString('cellularApnUseDefault');
932 defaultOption
.value
= -1;
933 // Add 'default' entry before 'other' option
934 apnSelector
.add(defaultOption
, otherOption
);
935 assert(apnSelector
.length
== 2); // 'default', 'other'
936 this.selectedApnIndex_
= 0; // Select 'default'
938 assert(this.selectedApnIndex_
>= 0);
939 apnSelector
.selectedIndex
= this.selectedApnIndex_
;
940 updateHidden('.apn-list-view', false);
941 updateHidden('.apn-details-view', true);
945 * Helper function for setting APN properties.
946 * @param {Object} apnValue Dictionary of APN properties.
949 setActiveApn_: function(apnValue
) {
951 var apnName
= apnValue
['AccessPointName'];
953 activeApn
['AccessPointName'] = apnName
;
954 activeApn
['Username'] = stringFromValue(apnValue
['Username']);
955 activeApn
['Password'] = stringFromValue(apnValue
['Password']);
957 // Set the cached ONC data.
958 this.onc_
.setProperty('Cellular.APN', activeApn
);
959 // Set an ONC object with just the APN values.
960 var oncData
= new OncData({});
961 oncData
.setProperty('Cellular.APN', activeApn
);
962 chrome
.networkingPrivate
.setProperties(this.onc_
.guid(),
967 * Event Listener for the cellular-apn-use-default button.
970 setDefaultApn_: function() {
971 var apnSelector
= $('select-apn');
973 // Remove the 'user' entry if it exists.
974 if (this.userApnIndex_
!= -1) {
975 assert(this.userApnIndex_
< apnSelector
.length
- 1);
976 apnSelector
.remove(this.userApnIndex_
);
977 this.userApnIndex_
= -1;
980 var apnList
= this.onc_
.getActiveValue('Cellular.APNList');
981 var iApn
= (apnList
!= undefined && apnList
.length
> 0) ? 0 : -1;
982 apnSelector
.selectedIndex
= iApn
;
983 this.selectedApnIndex_
= iApn
;
985 // Clear any user APN entry to inform Chrome to use the default APN.
986 this.setActiveApn_({});
988 updateHidden('.apn-list-view', false);
989 updateHidden('.apn-details-view', true);
993 * Event Listener for the cellular-apn-set button.
996 setApn_: function(apnValue
) {
1000 var apnSelector
= $('select-apn');
1003 activeApn
['AccessPointName'] = stringFromValue(apnValue
);
1004 activeApn
['Username'] = stringFromValue($('cellular-apn-username').value
);
1005 activeApn
['Password'] = stringFromValue($('cellular-apn-password').value
);
1006 this.setActiveApn_(activeApn
);
1007 // Set the user selected APN.
1008 this.userApn_
= activeApn
;
1010 // Remove any existing 'user' entry.
1011 if (this.userApnIndex_
!= -1) {
1012 assert(this.userApnIndex_
< apnSelector
.length
- 1);
1013 apnSelector
.remove(this.userApnIndex_
);
1014 this.userApnIndex_
= -1;
1017 // Create a new 'user' entry with the new active apn.
1018 var option
= document
.createElement('option');
1019 option
.textContent
= activeApn
['AccessPointName'];
1021 option
.selected
= true;
1022 this.insertApnUserOption_(option
);
1024 updateHidden('.apn-list-view', false);
1025 updateHidden('.apn-details-view', true);
1029 * Event Listener for the cellular-apn-cancel button.
1032 cancelApn_: function() { this.initializeApnList_(); },
1035 * Event Listener for the select-apn button.
1038 selectApn_: function() {
1039 var onc
= this.onc_
;
1040 var apnSelector
= $('select-apn');
1041 if (apnSelector
[apnSelector
.selectedIndex
].value
!= -1) {
1042 var apnList
= onc
.getActiveValue('Cellular.APNList');
1043 var apnIndex
= apnSelector
.selectedIndex
;
1044 assert(apnIndex
< apnList
.length
);
1045 this.selectedApnIndex_
= apnIndex
;
1046 this.setActiveApn_(apnList
[apnIndex
]);
1047 } else if (apnSelector
.selectedIndex
== this.userApnIndex_
) {
1048 this.selectedApnIndex_
= apnSelector
.selectedIndex
;
1049 this.setActiveApn_(this.userApn_
);
1052 if (this.userApn_
['AccessPointName']) {
1053 // Fill in the details fields with the existing 'user' config.
1054 apnDict
= this.userApn_
;
1056 // No 'user' config, use the current values.
1058 apnDict
['AccessPointName'] =
1059 onc
.getActiveValue('Cellular.APN.AccessPointName');
1060 apnDict
['Username'] = onc
.getActiveValue('Cellular.APN.Username');
1061 apnDict
['Password'] = onc
.getActiveValue('Cellular.APN.Password');
1063 $('cellular-apn').value
= stringFromValue(apnDict
['AccessPointName']);
1064 $('cellular-apn-username').value
= stringFromValue(apnDict
['Username']);
1065 $('cellular-apn-password').value
= stringFromValue(apnDict
['Password']);
1066 updateHidden('.apn-list-view', true);
1067 updateHidden('.apn-details-view', false);
1073 * Enables or Disables all buttons that provide operations on the cellular
1076 DetailsInternetPage
.changeCellularButtonsState = function(disable
) {
1077 var buttonsToDisableList
=
1078 new Array('details-internet-login',
1079 'details-internet-disconnect',
1080 'details-internet-configure',
1082 'view-account-details');
1084 for (var i
= 0; i
< buttonsToDisableList
.length
; ++i
) {
1085 var button
= $(buttonsToDisableList
[i
]);
1086 button
.disabled
= disable
;
1091 * If the network is not already activated, starts the activation process or
1092 * shows the activation UI. Otherwise does nothing.
1094 DetailsInternetPage
.activateCellular = function(guid
) {
1095 chrome
.networkingPrivate
.getProperties(guid
, function(properties
) {
1096 var oncData
= new OncData(properties
);
1097 if (oncData
.getActiveValue('Cellular.ActivationState') == 'Activated') {
1100 var carrier
= oncData
.getActiveValue('Cellular.Carrier');
1101 if (carrier
== CarrierSprint
) {
1102 // Sprint is directly ativated, call startActivate().
1103 chrome
.networkingPrivate
.startActivate(guid
, '');
1105 chrome
.send('showMorePlanInfo', [guid
]);
1111 * Performs minimal initialization of the InternetDetails dialog in
1112 * preparation for showing proxy-settings.
1114 DetailsInternetPage
.initializeProxySettings = function() {
1115 DetailsInternetPage
.getInstance().initializePageContents_();
1119 * Displays the InternetDetails dialog with only the proxy settings visible.
1121 DetailsInternetPage
.showProxySettings = function() {
1122 var detailsPage
= DetailsInternetPage
.getInstance();
1123 $('network-details-header').hidden
= true;
1124 $('activate-details').hidden
= true;
1125 $('view-account-details').hidden
= true;
1126 $('web-proxy-auto-discovery').hidden
= true;
1127 detailsPage
.showProxy_
= true;
1128 updateHidden('#internet-tab', true);
1129 updateHidden('#details-tab-strip', true);
1130 updateHidden('#details-internet-page .action-area', true);
1131 detailsPage
.updateControls();
1132 detailsPage
.visible
= true;
1133 sendChromeMetricsAction('Options_NetworkShowProxyTab');
1137 * Initializes even handling for keyboard driven flow.
1139 DetailsInternetPage
.initializeKeyboardFlow = function() {
1140 keyboard
.initializeKeyboardFlow();
1143 DetailsInternetPage
.updateProxySettings = function(type
) {
1144 var proxyHost
= null,
1147 if (type
== 'cros.session.proxy.singlehttp') {
1148 proxyHost
= 'proxy-host-single-name';
1149 proxyPort
= 'proxy-host-single-port';
1150 } else if (type
== 'cros.session.proxy.httpurl') {
1151 proxyHost
= 'proxy-host-name';
1152 proxyPort
= 'proxy-host-port';
1153 } else if (type
== 'cros.session.proxy.httpsurl') {
1154 proxyHost
= 'secure-proxy-host-name';
1155 proxyPort
= 'secure-proxy-port';
1156 } else if (type
== 'cros.session.proxy.ftpurl') {
1157 proxyHost
= 'ftp-proxy';
1158 proxyPort
= 'ftp-proxy-port';
1159 } else if (type
== 'cros.session.proxy.socks') {
1160 proxyHost
= 'socks-host';
1161 proxyPort
= 'socks-port';
1166 var hostValue
= $(proxyHost
).value
;
1167 if (hostValue
.indexOf(':') !== -1) {
1168 if (hostValue
.match(/:/g
).length
== 1) {
1169 hostValue
= hostValue
.split(':');
1170 $(proxyHost
).value
= hostValue
[0];
1171 $(proxyPort
).value
= hostValue
[1];
1176 DetailsInternetPage
.loginFromDetails = function() {
1177 DetailsInternetPage
.configureOrConnect();
1178 PageManager
.closeOverlay();
1182 * This function identifies unconfigured networks and networks that are
1183 * likely to fail (e.g. due to a bad passphrase on a previous connect
1184 * attempt). For such networks a configure dialog will be opened. Otherwise
1185 * a connection will be attempted.
1187 DetailsInternetPage
.configureOrConnect = function() {
1188 var detailsPage
= DetailsInternetPage
.getInstance();
1189 if (detailsPage
.type_
== 'WiFi')
1190 sendChromeMetricsAction('Options_NetworkConnectToWifi');
1191 else if (detailsPage
.type_
== 'VPN')
1192 sendChromeMetricsAction('Options_NetworkConnectToVPN');
1194 var onc
= detailsPage
.onc_
;
1195 var guid
= onc
.guid();
1196 var type
= onc
.getActiveValue('Type');
1198 // Built-in VPNs do not correctly set 'Connectable', so we always show the
1199 // configuration UI.
1200 if (type
== 'VPN') {
1201 if (onc
.getActiveValue('VPN.Type') != 'ThirdPartyVPN') {
1202 chrome
.send('configureNetwork', [guid
]);
1207 // If 'Connectable' is false for WiFi or WiMAX, Shill requires
1208 // additional configuration to connect, so show the configuration UI.
1209 if ((type
== 'WiFi' || type
== 'WiMAX') &&
1210 !onc
.getActiveValue('Connectable')) {
1211 chrome
.send('configureNetwork', [guid
]);
1215 // Secure WiFi networks with ErrorState set most likely require
1216 // configuration (e.g. a correct passphrase) before connecting.
1217 if (type
== 'WiFi' && onc
.getWiFiSecurity() != 'None') {
1218 var errorState
= onc
.getActiveValue('ErrorState');
1219 if (errorState
&& errorState
!= 'Unknown') {
1220 chrome
.send('configureNetwork', [guid
]);
1225 // Cellular networks need to be activated before they can be connected to.
1226 if (type
== 'Cellular') {
1227 var activationState
= onc
.getActiveValue('Cellular.ActivationState');
1228 if (activationState
!= 'Activated' && activationState
!= 'Unknown') {
1229 DetailsInternetPage
.activateCellular(guid
);
1234 chrome
.networkingPrivate
.startConnect(guid
);
1237 DetailsInternetPage
.disconnectNetwork = function() {
1238 var detailsPage
= DetailsInternetPage
.getInstance();
1239 if (detailsPage
.type_
== 'WiFi')
1240 sendChromeMetricsAction('Options_NetworkDisconnectWifi');
1241 else if (detailsPage
.type_
== 'VPN')
1242 sendChromeMetricsAction('Options_NetworkDisconnectVPN');
1243 chrome
.networkingPrivate
.startDisconnect(detailsPage
.onc_
.guid());
1244 PageManager
.closeOverlay();
1247 DetailsInternetPage
.configureNetwork = function() {
1248 var detailsPage
= DetailsInternetPage
.getInstance();
1249 // This is an explicit request to show the configure dialog; do not show
1250 // the enrollment dialog for networks missing a certificate.
1251 var forceShow
= true;
1252 chrome
.send('configureNetwork', [detailsPage
.onc_
.guid(), forceShow
]);
1253 PageManager
.closeOverlay();
1256 DetailsInternetPage
.activateFromDetails = function() {
1257 var detailsPage
= DetailsInternetPage
.getInstance();
1258 if (detailsPage
.type_
== 'Cellular')
1259 DetailsInternetPage
.activateCellular(detailsPage
.onc_
.guid());
1260 PageManager
.closeOverlay();
1264 * Event handler called when the details page is closed. Sends changed
1265 * properties to Chrome and closes the overlay.
1267 DetailsInternetPage
.setDetails = function() {
1268 var detailsPage
= DetailsInternetPage
.getInstance();
1269 var type
= detailsPage
.type_
;
1270 var oncData
= new OncData({});
1271 var autoConnectCheckboxId
= '';
1272 if (type
== 'WiFi') {
1273 var preferredCheckbox
=
1274 assertInstanceof($('prefer-network-wifi'), HTMLInputElement
);
1275 if (!preferredCheckbox
.hidden
&& !preferredCheckbox
.disabled
) {
1276 var kPreferredPriority
= 1;
1277 var priority
= preferredCheckbox
.checked
? kPreferredPriority
: 0;
1278 oncData
.setProperty('Priority', priority
);
1279 sendChromeMetricsAction('Options_NetworkSetPrefer');
1281 autoConnectCheckboxId
= 'auto-connect-network-wifi';
1282 } else if (type
== 'WiMAX') {
1283 autoConnectCheckboxId
= 'auto-connect-network-wimax';
1284 } else if (type
== 'Cellular') {
1285 autoConnectCheckboxId
= 'auto-connect-network-cellular';
1286 } else if (type
== 'VPN') {
1287 var providerType
= detailsPage
.onc_
.getActiveValue('VPN.Type');
1288 if (providerType
!= 'ThirdPartyVPN') {
1289 oncData
.setProperty('VPN.Type', providerType
);
1290 oncData
.setProperty('VPN.Host', $('inet-server-hostname').value
);
1291 autoConnectCheckboxId
= 'auto-connect-network-vpn';
1294 if (autoConnectCheckboxId
!= '') {
1295 var autoConnectCheckbox
=
1296 assertInstanceof($(autoConnectCheckboxId
), HTMLInputElement
);
1297 if (!autoConnectCheckbox
.hidden
&& !autoConnectCheckbox
.disabled
) {
1298 var autoConnectKey
= type
+ '.AutoConnect';
1299 oncData
.setProperty(autoConnectKey
, !!autoConnectCheckbox
.checked
);
1300 sendChromeMetricsAction('Options_NetworkAutoConnect');
1304 var nameServerTypes
= ['automatic', 'google', 'user'];
1305 var nameServerType
= 'automatic';
1306 for (var i
= 0; i
< nameServerTypes
.length
; ++i
) {
1307 if ($(nameServerTypes
[i
] + '-dns-radio').checked
) {
1308 nameServerType
= nameServerTypes
[i
];
1312 var ipConfig
= detailsPage
.getIpConfig_(nameServerType
);
1313 var ipAddressType
= ('IPAddress' in ipConfig
) ? 'Static' : 'DHCP';
1314 var nameServersType
= ('NameServers' in ipConfig
) ? 'Static' : 'DHCP';
1315 oncData
.setProperty('IPAddressConfigType', ipAddressType
);
1316 oncData
.setProperty('NameServersConfigType', nameServersType
);
1317 oncData
.setProperty('StaticIPConfig', ipConfig
);
1319 var data
= oncData
.getData();
1320 if (Object
.keys(data
).length
> 0) {
1321 // TODO(stevenjb): Only set changed properties.
1322 chrome
.networkingPrivate
.setProperties(detailsPage
.onc_
.guid(), data
);
1325 PageManager
.closeOverlay();
1329 * Event handler called when the name server type changes.
1330 * @param {string} type The selected name sever type, 'automatic', 'google',
1333 DetailsInternetPage
.updateNameServerDisplay = function(type
) {
1334 var editable
= type
== 'user';
1335 var fields
= [$('ipconfig-dns1'), $('ipconfig-dns2'),
1336 $('ipconfig-dns3'), $('ipconfig-dns4')];
1337 for (var i
= 0; i
< fields
.length
; ++i
) {
1338 fields
[i
].editable
= editable
;
1341 $('ipconfig-dns1').focus();
1343 var automaticDns
= $('automatic-dns-display');
1344 var googleDns
= $('google-dns-display');
1345 var userDns
= $('user-dns-settings');
1348 automaticDns
.setAttribute('selected', '');
1349 googleDns
.removeAttribute('selected');
1350 userDns
.removeAttribute('selected');
1353 automaticDns
.removeAttribute('selected');
1354 googleDns
.setAttribute('selected', '');
1355 userDns
.removeAttribute('selected');
1358 automaticDns
.removeAttribute('selected');
1359 googleDns
.removeAttribute('selected');
1360 userDns
.setAttribute('selected', '');
1366 * Method called from Chrome when the ONC properties for the displayed
1367 * network may have changed.
1368 * @param {Object} oncData The updated ONC dictionary for the network.
1370 DetailsInternetPage
.updateConnectionData = function(oncData
) {
1371 var detailsPage
= DetailsInternetPage
.getInstance();
1372 if (!detailsPage
.visible
)
1375 if (oncData
.GUID
!= detailsPage
.onc_
.guid())
1378 // Update our cached data object.
1379 detailsPage
.onc_
= new OncData(oncData
);
1381 detailsPage
.populateHeader_();
1382 detailsPage
.updateConnectionButtonVisibilty_();
1383 detailsPage
.updateDetails_();
1387 * Initializes the details page with the provided ONC data.
1388 * @param {Object} oncData Dictionary of ONC properties.
1390 DetailsInternetPage
.initializeDetailsPage = function(oncData
) {
1391 var onc
= new OncData(oncData
);
1393 var detailsPage
= DetailsInternetPage
.getInstance();
1394 detailsPage
.onc_
= onc
;
1395 var type
= onc
.getActiveValue('Type');
1396 detailsPage
.type_
= type
;
1398 sendShowDetailsMetrics(type
, onc
.getActiveValue('ConnectionState'));
1400 if (type
== 'VPN') {
1401 // Cache the dialog title, which will contain the provider name in the
1402 // case of a third-party VPN provider. This caching is important as the
1403 // provider may go away while the details dialog is being shown, causing
1404 // subsequent updates to be unable to determine the correct title.
1405 detailsPage
.networkTitle_
= options
.VPNProviders
.formatNetworkName(onc
);
1407 delete detailsPage
.networkTitle_
;
1410 detailsPage
.populateHeader_();
1411 detailsPage
.updateConnectionButtonVisibilty_();
1412 detailsPage
.updateDetails_();
1414 // TODO(stevenjb): Some of the setup below should be moved to
1415 // updateDetails_() so that updates are reflected in the UI.
1417 // Only show proxy for remembered networks.
1418 var remembered
= onc
.getSource() != 'None';
1420 detailsPage
.showProxy_
= true;
1421 // Inform Chrome which network to use for proxy configuration.
1422 chrome
.send('selectNetwork', [detailsPage
.onc_
.guid()]);
1424 detailsPage
.showProxy_
= false;
1427 $('web-proxy-auto-discovery').hidden
= true;
1429 var restricted
= onc
.getActiveValue('RestrictedConnectivity');
1430 var restrictedString
= loadTimeData
.getString(
1431 restricted
? 'restrictedYes' : 'restrictedNo');
1433 // These objects contain an 'automatic' property that is displayed when
1434 // ip-automatic-configuration-checkbox is checked, and a 'value' property
1435 // that is displayed when unchecked and used to set the associated ONC
1436 // property for StaticIPConfig on commit.
1437 var inetAddress
= {};
1438 var inetNetmask
= {};
1439 var inetGateway
= {};
1441 var inetNameServersString
;
1443 var ipconfigList
= onc
.getActiveValue('IPConfigs');
1444 if (Array
.isArray(ipconfigList
)) {
1445 for (var i
= 0; i
< ipconfigList
.length
; ++i
) {
1446 var ipconfig
= ipconfigList
[i
];
1447 var ipType
= ipconfig
['Type'];
1448 if (ipType
!= 'IPv4') {
1449 // TODO(stevenjb): Handle IPv6 properties.
1452 var address
= ipconfig
['IPAddress'];
1453 inetAddress
.automatic
= address
;
1454 inetAddress
.value
= address
;
1455 var netmask
= prefixLengthToNetmask(ipconfig
['RoutingPrefix']);
1456 inetNetmask
.automatic
= netmask
;
1457 inetNetmask
.value
= netmask
;
1458 var gateway
= ipconfig
['Gateway'];
1459 inetGateway
.automatic
= gateway
;
1460 inetGateway
.value
= gateway
;
1461 if ('WebProxyAutoDiscoveryUrl' in ipconfig
) {
1462 $('web-proxy-auto-discovery').hidden
= false;
1463 $('web-proxy-auto-discovery-url').value
=
1464 ipconfig
['WebProxyAutoDiscoveryUrl'];
1466 if ('NameServers' in ipconfig
) {
1467 var inetNameServers
= ipconfig
['NameServers'];
1468 inetNameServers
= inetNameServers
.sort();
1469 inetNameServersString
= inetNameServers
.join(',');
1471 break; // Use the first IPv4 entry.
1475 // Override the 'automatic' properties with the saved DHCP values if the
1476 // saved value is set, and set any unset 'value' properties.
1477 var savedNameServersString
;
1478 var savedIpAddress
= onc
.getActiveValue('SavedIPConfig.IPAddress');
1479 if (savedIpAddress
!= undefined) {
1480 inetAddress
.automatic
= savedIpAddress
;
1481 if (!inetAddress
.value
)
1482 inetAddress
.value
= savedIpAddress
;
1484 var savedPrefix
= onc
.getActiveValue('SavedIPConfig.RoutingPrefix');
1485 if (savedPrefix
!= undefined) {
1486 assert(typeof savedPrefix
== 'number');
1487 var savedNetmask
= prefixLengthToNetmask(
1488 /** @type {number} */(savedPrefix
));
1489 inetNetmask
.automatic
= savedNetmask
;
1490 if (!inetNetmask
.value
)
1491 inetNetmask
.value
= savedNetmask
;
1493 var savedGateway
= onc
.getActiveValue('SavedIPConfig.Gateway');
1494 if (savedGateway
!= undefined) {
1495 inetGateway
.automatic
= savedGateway
;
1496 if (!inetGateway
.value
)
1497 inetGateway
.value
= savedGateway
;
1500 var savedNameServers
= onc
.getActiveValue('SavedIPConfig.NameServers');
1501 if (savedNameServers
) {
1502 savedNameServers
= savedNameServers
.sort();
1503 savedNameServersString
= savedNameServers
.join(',');
1506 var ipAutoConfig
= 'automatic';
1507 if (onc
.getActiveValue('IPAddressConfigType') == 'Static') {
1508 ipAutoConfig
= 'user';
1509 var staticIpAddress
= onc
.getActiveValue('StaticIPConfig.IPAddress');
1510 inetAddress
.user
= staticIpAddress
;
1511 inetAddress
.value
= staticIpAddress
;
1513 var staticPrefix
= onc
.getActiveValue('StaticIPConfig.RoutingPrefix');
1514 if (typeof staticPrefix
!= 'number')
1516 var staticNetmask
= prefixLengthToNetmask(
1517 /** @type {number} */ (staticPrefix
));
1518 inetNetmask
.user
= staticNetmask
;
1519 inetNetmask
.value
= staticNetmask
;
1521 var staticGateway
= onc
.getActiveValue('StaticIPConfig.Gateway');
1522 inetGateway
.user
= staticGateway
;
1523 inetGateway
.value
= staticGateway
;
1526 var staticNameServersString
;
1527 if (onc
.getActiveValue('NameServersConfigType') == 'Static') {
1528 var staticNameServers
= onc
.getActiveValue('StaticIPConfig.NameServers');
1529 staticNameServers
= staticNameServers
.sort();
1530 staticNameServersString
= staticNameServers
.join(',');
1533 $('ip-automatic-configuration-checkbox').checked
=
1534 ipAutoConfig
== 'automatic';
1536 inetAddress
.autoConfig
= ipAutoConfig
;
1537 inetNetmask
.autoConfig
= ipAutoConfig
;
1538 inetGateway
.autoConfig
= ipAutoConfig
;
1540 var configureAddressField = function(field
, model
) {
1541 IPAddressField
.decorate(field
);
1542 field
.model
= model
;
1543 field
.editable
= model
.autoConfig
== 'user';
1545 configureAddressField($('ip-address'), inetAddress
);
1546 configureAddressField($('ip-netmask'), inetNetmask
);
1547 configureAddressField($('ip-gateway'), inetGateway
);
1549 // Set Nameserver fields. Nameservers are 'automatic' by default. If a
1550 // static namerserver is set, use that unless it does not match a non
1551 // empty 'NameServers' value (indicating that the custom nameservers are
1552 // invalid or not being applied for some reason). TODO(stevenjb): Only
1553 // set these properites if they change so that invalid custom values do
1555 var nameServerType
= 'automatic';
1556 if (staticNameServersString
&&
1557 (!inetNameServersString
||
1558 staticNameServersString
== inetNameServersString
)) {
1559 if (staticNameServersString
== GoogleNameServers
.join(','))
1560 nameServerType
= 'google';
1562 nameServerType
= 'user';
1564 if (nameServerType
== 'automatic')
1565 $('automatic-dns-display').textContent
= inetNameServersString
;
1567 $('automatic-dns-display').textContent
= savedNameServersString
;
1568 $('google-dns-display').textContent
= GoogleNameServers
.join(',');
1570 var nameServersUser
= [];
1571 if (staticNameServers
) {
1572 nameServersUser
= staticNameServers
;
1573 } else if (savedNameServers
) {
1574 // Pre-populate with values provided by DHCP server.
1575 nameServersUser
= savedNameServers
;
1578 var nameServerModels
= [];
1579 for (var i
= 0; i
< 4; ++i
)
1580 nameServerModels
.push({value
: nameServersUser
[i
] || ''});
1582 $(nameServerType
+ '-dns-radio').checked
= true;
1583 configureAddressField($('ipconfig-dns1'), nameServerModels
[0]);
1584 configureAddressField($('ipconfig-dns2'), nameServerModels
[1]);
1585 configureAddressField($('ipconfig-dns3'), nameServerModels
[2]);
1586 configureAddressField($('ipconfig-dns4'), nameServerModels
[3]);
1588 DetailsInternetPage
.updateNameServerDisplay(nameServerType
);
1590 var macAddress
= onc
.getActiveValue('MacAddress');
1592 $('hardware-address').textContent
= macAddress
;
1593 $('hardware-address-row').style
.display
= 'table-row';
1595 // This is most likely a device without a hardware address.
1596 $('hardware-address-row').style
.display
= 'none';
1599 var setOrHideParent = function(field
, property
) {
1600 if (property
!= undefined) {
1601 $(field
).textContent
= property
;
1602 $(field
).parentElement
.hidden
= false;
1604 $(field
).parentElement
.hidden
= true;
1608 var networkName
= onc
.getTranslatedValue('Name');
1610 // Signal strength as percentage (for WiFi and WiMAX).
1612 if (type
== 'WiFi' || type
== 'WiMAX')
1613 signalStrength
= onc
.getActiveValue(type
+ '.SignalStrength');
1614 if (!signalStrength
)
1616 var strengthFormat
= loadTimeData
.getString('inetSignalStrengthFormat');
1617 var strengthString
= strengthFormat
.replace('$1', signalStrength
);
1619 if (type
== 'WiFi') {
1620 OptionsPage
.showTab($('wifi-network-nav-tab'));
1621 $('wifi-restricted-connectivity').textContent
= restrictedString
;
1622 var ssid
= onc
.getActiveValue('WiFi.SSID');
1623 $('wifi-ssid').textContent
= ssid
? ssid
: networkName
;
1624 setOrHideParent('wifi-bssid', onc
.getActiveValue('WiFi.BSSID'));
1625 var security
= onc
.getWiFiSecurity();
1626 if (security
== 'None')
1627 security
= undefined;
1628 setOrHideParent('wifi-security', security
);
1629 // Frequency is in MHz.
1630 var frequency
= onc
.getActiveValue('WiFi.Frequency');
1633 var frequencyFormat
= loadTimeData
.getString('inetFrequencyFormat');
1634 frequencyFormat
= frequencyFormat
.replace('$1', frequency
);
1635 $('wifi-frequency').textContent
= frequencyFormat
;
1636 $('wifi-signal-strength').textContent
= strengthString
;
1637 setOrHideParent('wifi-hardware-address',
1638 onc
.getActiveValue('MacAddress'));
1639 var priority
= onc
.getActiveValue('Priority');
1640 $('prefer-network-wifi').checked
= priority
> 0;
1641 $('prefer-network-wifi').disabled
= !remembered
;
1642 $('auto-connect-network-wifi').checked
=
1643 onc
.getActiveValue('WiFi.AutoConnect');
1644 $('auto-connect-network-wifi').disabled
= !remembered
;
1645 } else if (type
== 'WiMAX') {
1646 OptionsPage
.showTab($('wimax-network-nav-tab'));
1647 $('wimax-restricted-connectivity').textContent
= restrictedString
;
1649 $('auto-connect-network-wimax').checked
=
1650 onc
.getActiveValue('WiMAX.AutoConnect');
1651 $('auto-connect-network-wimax').disabled
= !remembered
;
1652 var identity
= onc
.getActiveValue('WiMAX.EAP.Identity');
1653 setOrHideParent('wimax-eap-identity', identity
);
1654 $('wimax-signal-strength').textContent
= strengthString
;
1655 } else if (type
== 'Cellular') {
1656 OptionsPage
.showTab($('cellular-conn-nav-tab'));
1658 var isGsm
= onc
.getActiveValue('Cellular.Family') == 'GSM';
1660 $('service-name').textContent
= networkName
;
1662 // TODO(stevenjb): Ideally many of these should be localized.
1663 $('network-technology').textContent
=
1664 onc
.getActiveValue('Cellular.NetworkTechnology');
1665 $('roaming-state').textContent
=
1666 onc
.getTranslatedValue('Cellular.RoamingState');
1667 $('cellular-restricted-connectivity').textContent
= restrictedString
;
1668 $('error-state').textContent
= onc
.getActiveValue('ErrorState');
1669 $('manufacturer').textContent
=
1670 onc
.getActiveValue('Cellular.Manufacturer');
1671 $('model-id').textContent
= onc
.getActiveValue('Cellular.ModelID');
1672 $('firmware-revision').textContent
=
1673 onc
.getActiveValue('Cellular.FirmwareRevision');
1674 $('hardware-revision').textContent
=
1675 onc
.getActiveValue('Cellular.HardwareRevision');
1676 $('mdn').textContent
= onc
.getActiveValue('Cellular.MDN');
1678 // Show ServingOperator properties only if available.
1679 var servingOperatorName
=
1680 onc
.getActiveValue('Cellular.ServingOperator.Name');
1681 var servingOperatorCode
=
1682 onc
.getActiveValue('Cellular.ServingOperator.Code');
1683 if (servingOperatorName
!= undefined &&
1684 servingOperatorCode
!= undefined) {
1685 $('operator-name').textContent
= servingOperatorName
;
1686 $('operator-code').textContent
= servingOperatorCode
;
1688 $('operator-name').parentElement
.hidden
= true;
1689 $('operator-code').parentElement
.hidden
= true;
1691 // Make sure that GSM/CDMA specific properties that shouldn't be hidden
1693 updateHidden('#details-internet-page .gsm-only', false);
1694 updateHidden('#details-internet-page .cdma-only', false);
1696 // Show IMEI/ESN/MEID/MIN/PRL only if they are available.
1697 setOrHideParent('esn', onc
.getActiveValue('Cellular.ESN'));
1698 setOrHideParent('imei', onc
.getActiveValue('Cellular.IMEI'));
1699 setOrHideParent('meid', onc
.getActiveValue('Cellular.MEID'));
1700 setOrHideParent('min', onc
.getActiveValue('Cellular.MIN'));
1701 setOrHideParent('prl-version', onc
.getActiveValue('Cellular.PRLVersion'));
1704 $('iccid').textContent
= onc
.getActiveValue('Cellular.ICCID');
1705 $('imsi').textContent
= onc
.getActiveValue('Cellular.IMSI');
1706 detailsPage
.initializeApnList_();
1708 $('auto-connect-network-cellular').checked
=
1709 onc
.getActiveValue('Cellular.AutoConnect');
1710 $('auto-connect-network-cellular').disabled
= false;
1711 } else if (type
== 'VPN') {
1712 OptionsPage
.showTab($('vpn-nav-tab'));
1713 var providerType
= onc
.getActiveValue('VPN.Type');
1714 var isThirdPartyVPN
= providerType
== 'ThirdPartyVPN';
1715 $('vpn-tab').classList
.toggle('third-party-vpn-provider',
1718 $('inet-service-name').textContent
= networkName
;
1719 $('inet-provider-type').textContent
=
1720 onc
.getTranslatedValue('VPN.Type');
1722 if (isThirdPartyVPN
) {
1723 $('inet-provider-name').textContent
= '';
1724 var extensionID
= onc
.getActiveValue('VPN.ThirdPartyVPN.ExtensionID');
1725 var providers
= options
.VPNProviders
.getProviders();
1726 for (var i
= 0; i
< providers
.length
; ++i
) {
1727 if (extensionID
== providers
[i
].extensionID
) {
1728 $('inet-provider-name').textContent
= providers
[i
].name
;
1734 if (providerType
== 'OpenVPN')
1735 usernameKey
= 'VPN.OpenVPN.Username';
1736 else if (providerType
== 'L2TP-IPsec')
1737 usernameKey
= 'VPN.L2TP.Username';
1740 $('inet-username').parentElement
.hidden
= false;
1741 $('inet-username').textContent
= onc
.getActiveValue(usernameKey
);
1743 $('inet-username').parentElement
.hidden
= true;
1745 var inetServerHostname
= $('inet-server-hostname');
1746 inetServerHostname
.value
= onc
.getActiveValue('VPN.Host');
1747 inetServerHostname
.resetHandler = function() {
1748 PageManager
.hideBubble();
1749 var recommended
= onc
.getRecommendedValue('VPN.Host');
1750 if (recommended
!= undefined)
1751 inetServerHostname
.value
= recommended
;
1753 $('auto-connect-network-vpn').checked
=
1754 onc
.getActiveValue('VPN.AutoConnect');
1755 $('auto-connect-network-vpn').disabled
= false;
1758 OptionsPage
.showTab($('internet-nav-tab'));
1761 // Update controlled option indicators.
1762 var indicators
= cr
.doc
.querySelectorAll(
1763 '#details-internet-page .controlled-setting-indicator');
1764 for (var i
= 0; i
< indicators
.length
; i
++) {
1765 var managed
= indicators
[i
].hasAttribute('managed');
1766 // TODO(stevenjb): Eliminate support for 'data' once 39 is stable.
1767 var attributeName
= managed
? 'managed' : 'data';
1768 var propName
= indicators
[i
].getAttribute(attributeName
);
1771 var propValue
= managed
?
1772 onc
.getManagedProperty(propName
) :
1773 onc
.getActiveValue(propName
);
1774 // If the property is unset or unmanaged (i.e. not an Object) skip it.
1775 if (propValue
== undefined || (typeof propValue
!= 'object'))
1779 event
= detailsPage
.createManagedEvent_(propName
, propValue
);
1781 event
= detailsPage
.createControlledEvent_(propName
,
1782 /** @type {{value: *, controlledBy: *, recommendedValue: *}} */(
1784 indicators
[i
].handlePrefChange(event
);
1785 var forElement
= $(indicators
[i
].getAttribute('internet-detail-for'));
1787 if (event
.value
.controlledBy
== 'policy')
1788 forElement
.disabled
= true;
1789 if (forElement
.resetHandler
)
1790 indicators
[i
].resetHandler
= forElement
.resetHandler
;
1794 detailsPage
.updateControls();
1796 // Don't show page name in address bar and in history to prevent people
1797 // navigate here by hand and solve issue with page session restore.
1798 PageManager
.showPageByName('detailsInternetPage', false);
1802 DetailsInternetPage
: DetailsInternetPage