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.networkingPrivate.getManagedProperties(
253 guid, DetailsInternetPage.initializeDetailsPage);
257 * networkingPrivate callback when networks change.
258 * @param {Array<string>} changes List of GUIDs whose properties have
262 onNetworksChanged_: function(changes) {
265 var guid = this.onc_.guid();
266 if (changes.indexOf(guid) != -1) {
267 chrome.networkingPrivate.getManagedProperties(
268 guid, DetailsInternetPage.updateConnectionData);
273 * Initializes the contents of the page.
275 initializePageContents_: function() {
276 $('details-internet-dismiss').addEventListener('click', function(event) {
277 DetailsInternetPage.setDetails();
280 $('details-internet-login').addEventListener('click', function(event) {
281 DetailsInternetPage.setDetails();
282 DetailsInternetPage.loginFromDetails();
285 $('details-internet-disconnect').addEventListener('click',
287 DetailsInternetPage.setDetails();
288 DetailsInternetPage.disconnectNetwork();
291 $('details-internet-configure').addEventListener('click',
293 DetailsInternetPage.setDetails();
294 DetailsInternetPage.configureNetwork();
297 $('activate-details').addEventListener('click', function(event) {
298 DetailsInternetPage.activateFromDetails();
301 $('view-account-details').addEventListener('click', function(event) {
302 chrome.send('showMorePlanInfo',
303 [DetailsInternetPage.getInstance().onc_.guid()]);
304 PageManager.closeOverlay();
307 $('cellular-apn-use-default').addEventListener('click', function(event) {
308 DetailsInternetPage.getInstance().setDefaultApn_();
311 $('cellular-apn-set').addEventListener('click', function(event) {
312 DetailsInternetPage.getInstance().setApn_($('cellular-apn').value);
315 $('cellular-apn-cancel').addEventListener('click', function(event) {
316 DetailsInternetPage.getInstance().cancelApn_();
319 $('select-apn').addEventListener('change', function(event) {
320 DetailsInternetPage.getInstance().selectApn_();
323 $('sim-card-lock-enabled').addEventListener('click', function(event) {
324 var newValue = $('sim-card-lock-enabled').checked;
325 // Leave value as is because user needs to enter PIN code first.
326 // When PIN will be entered and value changed,
327 // we'll update UI to reflect that change.
328 $('sim-card-lock-enabled').checked = !newValue;
329 var operation = newValue ? 'setLocked' : 'setUnlocked';
330 chrome.send('simOperation', [operation]);
332 $('change-pin').addEventListener('click', function(event) {
333 chrome.send('simOperation', ['changePin']);
337 ['proxy-host-single-port',
342 ].forEach(function(id) {
343 options.PrefPortNumber.decorate($(id));
346 options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list'));
347 $('remove-host').addEventListener('click',
348 this.handleRemoveProxyExceptions_);
349 $('add-host').addEventListener('click', this.handleAddProxyException_);
350 $('direct-proxy').addEventListener('click', this.disableManualProxy_);
351 $('manual-proxy').addEventListener('click', this.enableManualProxy_);
352 $('auto-proxy').addEventListener('click', this.disableManualProxy_);
353 $('proxy-all-protocols').addEventListener('click',
354 this.toggleSingleProxy_);
355 $('proxy-use-pac-url').addEventListener('change',
356 this.handleAutoConfigProxy_);
358 observePrefsUI($('direct-proxy'));
359 observePrefsUI($('manual-proxy'));
360 observePrefsUI($('auto-proxy'));
361 observePrefsUI($('proxy-all-protocols'));
362 observePrefsUI($('proxy-use-pac-url'));
364 $('ip-automatic-configuration-checkbox').addEventListener('click',
365 this.handleIpAutoConfig_);
366 $('automatic-dns-radio').addEventListener('click',
367 this.handleNameServerTypeChange_);
368 $('google-dns-radio').addEventListener('click',
369 this.handleNameServerTypeChange_);
370 $('user-dns-radio').addEventListener('click',
371 this.handleNameServerTypeChange_);
373 // We only load this string if we have the string data available
374 // because the proxy settings page on the login screen re-uses the
375 // proxy sub-page from the internet options, and it doesn't ever
376 // show the DNS settings, so we don't need this string there.
377 // The string isn't available because
378 // chrome://settings-frame/strings.js (where the string is
379 // stored) is not accessible from the login screen.
380 // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login
381 // page is fixed. http://crbug.com/242865
382 if (loadTimeData.data_) {
383 $('google-dns-label').innerHTML =
384 loadTimeData.getString('googleNameServers');
389 * Handler for "add" event fired from userNameEdit.
390 * @param {Event} e Add event fired from userNameEdit.
393 handleAddProxyException_: function(e) {
394 var exception = $('new-host').value;
395 $('new-host').value = '';
397 exception = exception.trim();
399 $('ignored-host-list').addException(exception);
403 * Handler for when the remove button is clicked
404 * @param {Event} e The click event.
407 handleRemoveProxyExceptions_: function(e) {
408 var selectedItems = $('ignored-host-list').selectedItems;
409 for (var x = 0; x < selectedItems.length; x++) {
410 $('ignored-host-list').removeException(selectedItems[x]);
415 * Handler for when the IP automatic configuration checkbox is clicked.
416 * @param {Event} e The click event.
419 handleIpAutoConfig_: function(e) {
420 var checked = $('ip-automatic-configuration-checkbox').checked;
421 var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
422 for (var i = 0; i < fields.length; ++i) {
423 fields[i].editable = !checked;
425 var model = fields[i].model;
426 model.value = model.automatic;
427 fields[i].model = model;
431 $('ip-address').focus();
435 * Handler for when the name server selection changes.
436 * @param {Event} event The click event.
439 handleNameServerTypeChange_: function(event) {
440 var type = event.target.value;
441 DetailsInternetPage.updateNameServerDisplay(type);
445 * Gets the IPConfig ONC Object.
446 * @param {string} nameServerType The selected name server type:
447 * 'automatic', 'google', or 'user'.
448 * @return {Object} The IPConfig ONC object.
451 getIpConfig_: function(nameServerType) {
453 // If 'ip-address' is empty, automatic configuration will be used.
454 if (!$('ip-automatic-configuration-checkbox').checked &&
455 $('ip-address').model.value) {
456 ipConfig['IPAddress'] = $('ip-address').model.value;
457 var netmask = $('ip-netmask').model.value;
458 var routingPrefix = 0;
460 routingPrefix = netmaskToPrefixLength(netmask);
461 if (routingPrefix == -1) {
462 console.error('Invalid netmask: ' + netmask);
466 ipConfig['RoutingPrefix'] = routingPrefix;
467 ipConfig['Gateway'] = $('ip-gateway').model.value || '';
470 // Note: If no nameserver fields are set, automatic configuration will be
471 // used. TODO(stevenjb): Validate input fields.
472 if (nameServerType != 'automatic') {
473 var userNameServers = [];
474 if (nameServerType == 'google') {
475 userNameServers = GoogleNameServers.slice();
476 } else if (nameServerType == 'user') {
477 for (var i = 1; i <= 4; ++i) {
478 var nameServerField = $('ipconfig-dns' + i);
479 // Skip empty values.
480 if (nameServerField && nameServerField.model &&
481 nameServerField.model.value) {
482 userNameServers.push(nameServerField.model.value);
486 if (userNameServers.length)
487 ipConfig['NameServers'] = userNameServers.sort();
493 * Creates an indicator event for controlled properties using
494 * the same dictionary format as CoreOptionsHandler::CreateValueForPref.
495 * @param {string} name The name for the Event.
496 * @param {{value: *, controlledBy: *, recommendedValue: *}} propData
497 * Property dictionary.
500 createControlledEvent_: function(name, propData) {
501 assert('value' in propData && 'controlledBy' in propData &&
502 'recommendedValue' in propData);
503 var event = new Event(name);
505 value: propData.value,
506 controlledBy: propData.controlledBy,
507 recommendedValue: propData.recommendedValue
513 * Creates an indicator event for controlled properties using
514 * the ONC getManagedProperties dictionary format.
515 * @param {string} name The name for the Event.
516 * @param {Object} propData ONC managed network property dictionary.
519 createManagedEvent_: function(name, propData) {
520 var event = new Event(name);
523 // Set the current value and recommended value.
524 var activeValue = propData['Active'];
525 var effective = propData['Effective'];
526 if (activeValue == undefined)
527 activeValue = propData[effective];
528 event.value.value = activeValue;
530 // If a property is editable then it is not enforced, and 'controlledBy'
531 // is set to 'recommended' unless effective == {User|Shared}Setting, in
532 // which case the value was modified from the recommended value.
533 // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then
534 // the set value is mandated by the policy.
535 if (propData['UserEditable']) {
536 if (effective == 'UserPolicy')
537 event.value.controlledBy = 'recommended';
538 event.value.recommendedValue = propData['UserPolicy'];
539 } else if (propData['DeviceEditable']) {
540 if (effective == 'DevicePolicy')
541 event.value.controlledBy = 'recommended';
542 event.value.recommendedValue = propData['DevicePolicy'];
543 } else if (effective == 'UserPolicy' || effective == 'DevicePolicy') {
544 event.value.controlledBy = 'policy';
551 * Update details page controls.
553 updateControls: function() {
554 // Note: onc may be undefined when called from a pref update before
555 // initialized in initializeDetailsPage.
558 // Always show the ipconfig section. TODO(stevenjb): Improve the display
559 // for unconnected networks. Currently the IP address fields may be
560 // blank if the network is not connected.
561 $('ipconfig-section').hidden = false;
562 $('ipconfig-dns-section').hidden = false;
564 // Network type related.
565 updateHidden('#details-internet-page .cellular-details',
566 this.type_ != 'Cellular');
567 updateHidden('#details-internet-page .wifi-details',
568 this.type_ != 'WiFi');
569 updateHidden('#details-internet-page .wimax-details',
570 this.type_ != 'WiMAX');
571 updateHidden('#details-internet-page .vpn-details', this.type_ != 'VPN');
572 updateHidden('#details-internet-page .proxy-details', !this.showProxy_);
575 if (onc && this.type_ == 'Cellular') {
576 // Hide gsm/cdma specific elements.
577 if (onc.getActiveValue('Cellular.Family') == 'GSM')
578 updateHidden('#details-internet-page .cdma-only', true);
580 updateHidden('#details-internet-page .gsm-only', true);
585 // Hide network tab for VPN.
586 updateHidden('#details-internet-page .network-details',
587 this.type_ == 'VPN');
589 // Password and shared.
590 var source = onc ? onc.getSource() : 'None';
591 var shared = (source == 'Device' || source == 'DevicePolicy');
592 var security = onc ? onc.getWiFiSecurity() : 'None';
593 updateHidden('#details-internet-page #password-details',
594 this.type_ != 'WiFi' || security == 'None');
595 updateHidden('#details-internet-page #wifi-shared-network', !shared);
596 updateHidden('#details-internet-page #prefer-network', source == 'None');
599 updateHidden('#details-internet-page #wimax-shared-network', !shared);
602 this.updateProxyBannerVisibility_();
603 this.toggleSingleProxy_();
604 if ($('manual-proxy').checked)
605 this.enableManualProxy_();
607 this.disableManualProxy_();
611 * Updates info banner visibility state. This function shows the banner
612 * if proxy is managed or shared-proxies is off for shared network.
615 updateProxyBannerVisibility_: function() {
616 var bannerDiv = $('network-proxy-info-banner');
617 if (!loadTimeData.data_) {
618 // TODO(pneubeck): This temporarily prevents an exception below until
619 // i18n of the proxy dialog on the login page is
620 // fixed. http://crbug.com/242865
621 bannerDiv.hidden = true;
625 // Show banner and determine its message if necessary.
626 var controlledBy = $('direct-proxy').controlledBy;
627 if (!controlledBy || controlledBy == '') {
628 bannerDiv.hidden = true;
630 bannerDiv.hidden = false;
631 // The possible banner texts are loaded in proxy_handler.cc.
632 var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() +
633 controlledBy.slice(1);
634 $('banner-text').textContent = loadTimeData.getString(bannerText);
639 * Handler for when the user clicks on the checkbox to allow a
640 * single proxy usage.
643 toggleSingleProxy_: function() {
644 if ($('proxy-all-protocols').checked) {
645 $('multi-proxy').hidden = true;
646 $('single-proxy').hidden = false;
648 $('multi-proxy').hidden = false;
649 $('single-proxy').hidden = true;
654 * Handler for when the user clicks on the checkbox to enter
655 * auto configuration URL.
658 handleAutoConfigProxy_: function() {
659 $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked;
663 * Handler for selecting a radio button that will disable the manual
667 disableManualProxy_: function() {
668 $('ignored-host-list').disabled = true;
669 $('new-host').disabled = true;
670 $('remove-host').disabled = true;
671 $('add-host').disabled = true;
672 $('proxy-all-protocols').disabled = true;
673 $('proxy-host-name').disabled = true;
674 $('proxy-host-port').disabled = true;
675 $('proxy-host-single-name').disabled = true;
676 $('proxy-host-single-port').disabled = true;
677 $('secure-proxy-host-name').disabled = true;
678 $('secure-proxy-port').disabled = true;
679 $('ftp-proxy').disabled = true;
680 $('ftp-proxy-port').disabled = true;
681 $('socks-host').disabled = true;
682 $('socks-port').disabled = true;
683 $('proxy-use-pac-url').disabled = $('auto-proxy').disabled ||
684 !$('auto-proxy').checked;
685 $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled ||
686 !$('proxy-use-pac-url').checked;
687 $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
688 $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
689 sendChromeMetricsAction('Options_NetworkManualProxy_Disable');
693 * Handler for selecting a radio button that will enable the manual
697 enableManualProxy_: function() {
698 $('ignored-host-list').redraw();
699 var allDisabled = $('manual-proxy').disabled;
700 $('ignored-host-list').disabled = allDisabled;
701 $('new-host').disabled = allDisabled;
702 $('remove-host').disabled = allDisabled;
703 $('add-host').disabled = allDisabled;
704 $('proxy-all-protocols').disabled = allDisabled;
705 $('proxy-host-name').disabled = allDisabled;
706 $('proxy-host-port').disabled = allDisabled;
707 $('proxy-host-single-name').disabled = allDisabled;
708 $('proxy-host-single-port').disabled = allDisabled;
709 $('secure-proxy-host-name').disabled = allDisabled;
710 $('secure-proxy-port').disabled = allDisabled;
711 $('ftp-proxy').disabled = allDisabled;
712 $('ftp-proxy-port').disabled = allDisabled;
713 $('socks-host').disabled = allDisabled;
714 $('socks-port').disabled = allDisabled;
715 $('proxy-use-pac-url').disabled = true;
716 $('proxy-pac-url').disabled = true;
717 $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
718 $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
719 sendChromeMetricsAction('Options_NetworkManualProxy_Enable');
723 * Helper method called from initializeDetailsPage and updateConnectionData.
724 * Updates visibility/enabled of the login/disconnect/configure buttons.
727 updateConnectionButtonVisibility_: function() {
729 if (this.type_ == 'Ethernet') {
730 // Ethernet can never be connected or disconnected and can always be
731 // configured (e.g. to set security).
732 $('details-internet-login').hidden = true;
733 $('details-internet-disconnect').hidden = true;
734 $('details-internet-configure').hidden = false;
738 var connectable = onc.getActiveValue('Connectable');
739 var connectState = onc.getActiveValue('ConnectionState');
740 if (connectState == 'NotConnected') {
741 $('details-internet-disconnect').hidden = true;
742 $('details-internet-login').hidden = false;
743 // Connecting to an unconfigured network might trigger certificate
744 // installation UI. Until that gets handled here, always enable the
745 // Connect button for built-in networks.
746 var enabled = (this.type_ != 'VPN') ||
747 (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') ||
749 $('details-internet-login').disabled = !enabled;
751 $('details-internet-login').hidden = true;
752 $('details-internet-disconnect').hidden = false;
755 var showConfigure = false;
756 if (this.type_ == 'VPN') {
757 showConfigure = true;
758 } else if (this.type_ == 'WiMAX' && connectState == 'NotConnected') {
759 showConfigure = true;
760 } else if (this.type_ == 'WiFi') {
761 showConfigure = (connectState == 'NotConnected' &&
762 (!connectable || onc.getWiFiSecurity() != 'None'));
764 $('details-internet-configure').hidden = !showConfigure;
768 * Helper method called from initializeDetailsPage and updateConnectionData.
769 * Updates the connection state property and account / sim card links.
772 updateDetails_: function() {
775 var connectionStateString = onc.getTranslatedValue('ConnectionState');
776 $('connection-state').textContent = connectionStateString;
778 var type = this.type_;
779 var showViewAccount = false;
780 var showActivate = false;
781 if (type == 'WiFi') {
782 $('wifi-connection-state').textContent = connectionStateString;
783 } else if (type == 'WiMAX') {
784 $('wimax-connection-state').textContent = connectionStateString;
785 } else if (type == 'Cellular') {
786 $('activation-state').textContent =
787 onc.getTranslatedValue('Cellular.ActivationState');
788 if (onc.getActiveValue('Cellular.Family') == 'GSM') {
790 onc.getActiveValue('Cellular.SIMLockStatus.LockEnabled');
791 $('sim-card-lock-enabled').checked = lockEnabled;
792 $('change-pin').hidden = !lockEnabled;
794 showViewAccount = shouldShowViewAccountButton(onc);
795 var activationState = onc.getActiveValue('Cellular.ActivationState');
796 showActivate = (activationState == 'NotActivated' ||
797 activationState == 'PartiallyActivated');
800 $('view-account-details').hidden = !showViewAccount;
801 $('activate-details').hidden = !showActivate;
802 // If activation is not complete, hide the login button.
804 $('details-internet-login').hidden = true;
808 * Helper method called from initializeDetailsPage and updateConnectionData.
809 * Updates the fields in the header section of the details frame.
812 populateHeader_: function() {
815 var name = onc.getTranslatedValue('Name');
816 if (onc.getActiveValue('Type') == 'VPN' &&
817 onc.getActiveValue('VPN.Type') == 'ThirdPartyVPN') {
819 onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName') ||
820 loadTimeData.getString('defaultThirdPartyProviderName');
821 name = loadTimeData.getStringF('vpnNameTemplate', providerName, name);
823 $('network-details-title').textContent = name;
825 var connectionStateString = onc.getTranslatedValue('ConnectionState');
826 $('network-details-subtitle-status').textContent = connectionStateString;
829 var type = this.type_;
830 if (type == 'Ethernet')
831 typeKey = 'ethernetTitle';
832 else if (type == 'WiFi')
833 typeKey = 'wifiTitle';
834 else if (type == 'WiMAX')
835 typeKey = 'wimaxTitle';
836 else if (type == 'Cellular')
837 typeKey = 'cellularTitle';
838 else if (type == 'VPN')
839 typeKey = 'vpnTitle';
842 var typeLabel = $('network-details-subtitle-type');
843 var typeSeparator = $('network-details-subtitle-separator');
845 typeLabel.textContent = loadTimeData.getString(typeKey);
846 typeLabel.hidden = false;
847 typeSeparator.hidden = false;
849 typeLabel.hidden = true;
850 typeSeparator.hidden = true;
855 * Helper method to insert a 'user' option into the Apn list.
856 * @param {Object} userOption The 'user' apn dictionary
859 insertApnUserOption_: function(userOption) {
860 // Add the 'user' option before the last option ('other')
861 var apnSelector = $('select-apn');
862 assert(apnSelector.length > 0);
863 var otherOption = apnSelector[apnSelector.length - 1];
864 apnSelector.add(userOption, otherOption);
865 this.userApnIndex_ = apnSelector.length - 2;
866 this.selectedApnIndex_ = this.userApnIndex_;
870 * Helper method called from initializeApnList to populate the Apn list.
871 * @param {Array} apnList List of available APNs.
874 populateApnList_: function(apnList) {
876 var apnSelector = $('select-apn');
877 assert(apnSelector.length == 1);
878 var otherOption = apnSelector[0];
879 var activeApn = onc.getActiveValue('Cellular.APN.AccessPointName');
881 onc.getActiveValue('Cellular.LastGoodAPN.AccessPointName');
882 for (var i = 0; i < apnList.length; i++) {
883 var apnDict = apnList[i];
884 var localizedName = apnDict['LocalizedName'];
885 var name = localizedName ? localizedName : apnDict['Name'];
886 var accessPointName = apnDict['AccessPointName'];
887 var option = document.createElement('option');
889 name ? (name + ' (' + accessPointName + ')') : accessPointName;
891 // Insert new option before 'other' option.
892 apnSelector.add(option, otherOption);
893 if (this.selectedApnIndex_ != -1)
895 // If this matches the active Apn name, or LastGoodApn name (or there
896 // is no last good APN), set it as the selected Apn.
897 if ((activeApn == accessPointName) ||
898 (!activeApn && (!lastGoodApn || lastGoodApn == accessPointName))) {
899 this.selectedApnIndex_ = i;
902 if (this.selectedApnIndex_ == -1 && activeApn) {
903 this.userApn_ = activeApn;
904 // Create a 'user' entry for any active apn not in the list.
905 var userOption = document.createElement('option');
906 userOption.textContent = activeApn;
907 userOption.value = -1;
908 this.insertApnUserOption_(userOption);
913 * Helper method called from initializeDetailsPage to initialize the Apn
917 initializeApnList_: function() {
918 this.selectedApnIndex_ = -1;
919 this.userApnIndex_ = -1;
922 var apnSelector = $('select-apn');
924 // Clear APN lists, keep only last element, 'other'.
925 while (apnSelector.length != 1)
926 apnSelector.remove(0);
928 var apnList = onc.getActiveValue('Cellular.APNList');
930 // Populate the list with the existing APNs.
931 this.populateApnList_(apnList);
933 // Create a single 'default' entry.
934 var otherOption = apnSelector[0];
935 var defaultOption = document.createElement('option');
936 defaultOption.textContent =
937 loadTimeData.getString('cellularApnUseDefault');
938 defaultOption.value = -1;
939 // Add 'default' entry before 'other' option
940 apnSelector.add(defaultOption, otherOption);
941 assert(apnSelector.length == 2); // 'default', 'other'
942 this.selectedApnIndex_ = 0; // Select 'default'
944 assert(this.selectedApnIndex_ >= 0);
945 apnSelector.selectedIndex = this.selectedApnIndex_;
946 updateHidden('.apn-list-view', false);
947 updateHidden('.apn-details-view', true);
951 * Helper function for setting APN properties.
952 * @param {Object} apnValue Dictionary of APN properties.
955 setActiveApn_: function(apnValue) {
957 var apnName = apnValue['AccessPointName'];
959 activeApn['AccessPointName'] = apnName;
960 activeApn['Username'] = stringFromValue(apnValue['Username']);
961 activeApn['Password'] = stringFromValue(apnValue['Password']);
963 // Set the cached ONC data.
964 this.onc_.setProperty('Cellular.APN', activeApn);
965 // Set an ONC object with just the APN values.
966 var oncData = new OncData({});
967 oncData.setProperty('Cellular.APN', activeApn);
968 chrome.networkingPrivate.setProperties(this.onc_.guid(),
973 * Event Listener for the cellular-apn-use-default button.
976 setDefaultApn_: function() {
977 var apnSelector = $('select-apn');
979 // Remove the 'user' entry if it exists.
980 if (this.userApnIndex_ != -1) {
981 assert(this.userApnIndex_ < apnSelector.length - 1);
982 apnSelector.remove(this.userApnIndex_);
983 this.userApnIndex_ = -1;
986 var apnList = this.onc_.getActiveValue('Cellular.APNList');
987 var iApn = (apnList != undefined && apnList.length > 0) ? 0 : -1;
988 apnSelector.selectedIndex = iApn;
989 this.selectedApnIndex_ = iApn;
991 // Clear any user APN entry to inform Chrome to use the default APN.
992 this.setActiveApn_({});
994 updateHidden('.apn-list-view', false);
995 updateHidden('.apn-details-view', true);
999 * Event Listener for the cellular-apn-set button.
1002 setApn_: function(apnValue) {
1006 var apnSelector = $('select-apn');
1009 activeApn['AccessPointName'] = stringFromValue(apnValue);
1010 activeApn['Username'] = stringFromValue($('cellular-apn-username').value);
1011 activeApn['Password'] = stringFromValue($('cellular-apn-password').value);
1012 this.setActiveApn_(activeApn);
1013 // Set the user selected APN.
1014 this.userApn_ = activeApn;
1016 // Remove any existing 'user' entry.
1017 if (this.userApnIndex_ != -1) {
1018 assert(this.userApnIndex_ < apnSelector.length - 1);
1019 apnSelector.remove(this.userApnIndex_);
1020 this.userApnIndex_ = -1;
1023 // Create a new 'user' entry with the new active apn.
1024 var option = document.createElement('option');
1025 option.textContent = activeApn['AccessPointName'];
1027 option.selected = true;
1028 this.insertApnUserOption_(option);
1030 updateHidden('.apn-list-view', false);
1031 updateHidden('.apn-details-view', true);
1035 * Event Listener for the cellular-apn-cancel button.
1038 cancelApn_: function() { this.initializeApnList_(); },
1041 * Event Listener for the select-apn button.
1044 selectApn_: function() {
1045 var onc = this.onc_;
1046 var apnSelector = $('select-apn');
1047 if (apnSelector[apnSelector.selectedIndex].value != -1) {
1048 var apnList = onc.getActiveValue('Cellular.APNList');
1049 var apnIndex = apnSelector.selectedIndex;
1050 assert(apnIndex < apnList.length);
1051 this.selectedApnIndex_ = apnIndex;
1052 this.setActiveApn_(apnList[apnIndex]);
1053 } else if (apnSelector.selectedIndex == this.userApnIndex_) {
1054 this.selectedApnIndex_ = apnSelector.selectedIndex;
1055 this.setActiveApn_(this.userApn_);
1058 if (this.userApn_['AccessPointName']) {
1059 // Fill in the details fields with the existing 'user' config.
1060 apnDict = this.userApn_;
1062 // No 'user' config, use the current values.
1064 apnDict['AccessPointName'] =
1065 onc.getActiveValue('Cellular.APN.AccessPointName');
1066 apnDict['Username'] = onc.getActiveValue('Cellular.APN.Username');
1067 apnDict['Password'] = onc.getActiveValue('Cellular.APN.Password');
1069 $('cellular-apn').value = stringFromValue(apnDict['AccessPointName']);
1070 $('cellular-apn-username').value = stringFromValue(apnDict['Username']);
1071 $('cellular-apn-password').value = stringFromValue(apnDict['Password']);
1072 updateHidden('.apn-list-view', true);
1073 updateHidden('.apn-details-view', false);
1079 * Enables or Disables all buttons that provide operations on the cellular
1082 DetailsInternetPage.changeCellularButtonsState = function(disable) {
1083 var buttonsToDisableList =
1084 new Array('details-internet-login',
1085 'details-internet-disconnect',
1086 'details-internet-configure',
1088 'view-account-details');
1090 for (var i = 0; i < buttonsToDisableList.length; ++i) {
1091 var button = $(buttonsToDisableList[i]);
1092 button.disabled = disable;
1097 * If the network is not already activated, starts the activation process or
1098 * shows the activation UI. Otherwise does nothing.
1100 DetailsInternetPage.activateCellular = function(guid) {
1101 chrome.networkingPrivate.getProperties(guid, function(properties) {
1102 var oncData = new OncData(properties);
1103 if (oncData.getActiveValue('Cellular.ActivationState') == 'Activated') {
1106 var carrier = oncData.getActiveValue('Cellular.Carrier');
1107 if (carrier == CarrierSprint) {
1108 // Sprint is directly ativated, call startActivate().
1109 chrome.networkingPrivate.startActivate(guid, '');
1111 chrome.send('showMorePlanInfo', [guid]);
1117 * Performs minimal initialization of the InternetDetails dialog in
1118 * preparation for showing proxy-settings.
1120 DetailsInternetPage.initializeProxySettings = function() {
1121 DetailsInternetPage.getInstance().initializePageContents_();
1125 * Displays the InternetDetails dialog with only the proxy settings visible.
1127 DetailsInternetPage.showProxySettings = function() {
1128 var detailsPage = DetailsInternetPage.getInstance();
1129 $('network-details-header').hidden = true;
1130 $('activate-details').hidden = true;
1131 $('view-account-details').hidden = true;
1132 $('web-proxy-auto-discovery').hidden = true;
1133 detailsPage.showProxy_ = true;
1134 updateHidden('#internet-tab', true);
1135 updateHidden('#details-tab-strip', true);
1136 updateHidden('#details-internet-page .action-area', true);
1137 detailsPage.updateControls();
1138 detailsPage.visible = true;
1139 sendChromeMetricsAction('Options_NetworkShowProxyTab');
1143 * Initializes even handling for keyboard driven flow.
1145 DetailsInternetPage.initializeKeyboardFlow = function() {
1146 keyboard.initializeKeyboardFlow();
1149 DetailsInternetPage.updateProxySettings = function(type) {
1150 var proxyHost = null,
1153 if (type == 'cros.session.proxy.singlehttp') {
1154 proxyHost = 'proxy-host-single-name';
1155 proxyPort = 'proxy-host-single-port';
1156 } else if (type == 'cros.session.proxy.httpurl') {
1157 proxyHost = 'proxy-host-name';
1158 proxyPort = 'proxy-host-port';
1159 } else if (type == 'cros.session.proxy.httpsurl') {
1160 proxyHost = 'secure-proxy-host-name';
1161 proxyPort = 'secure-proxy-port';
1162 } else if (type == 'cros.session.proxy.ftpurl') {
1163 proxyHost = 'ftp-proxy';
1164 proxyPort = 'ftp-proxy-port';
1165 } else if (type == 'cros.session.proxy.socks') {
1166 proxyHost = 'socks-host';
1167 proxyPort = 'socks-port';
1172 var hostValue = $(proxyHost).value;
1173 if (hostValue.indexOf(':') !== -1) {
1174 if (hostValue.match(/:/g).length == 1) {
1175 hostValue = hostValue.split(':');
1176 $(proxyHost).value = hostValue[0];
1177 $(proxyPort).value = hostValue[1];
1182 DetailsInternetPage.loginFromDetails = function() {
1183 DetailsInternetPage.configureOrConnect();
1184 PageManager.closeOverlay();
1188 * This function identifies unconfigured networks and networks that are
1189 * likely to fail (e.g. due to a bad passphrase on a previous connect
1190 * attempt). For such networks a configure dialog will be opened. Otherwise
1191 * a connection will be attempted.
1193 DetailsInternetPage.configureOrConnect = function() {
1194 var detailsPage = DetailsInternetPage.getInstance();
1195 if (detailsPage.type_ == 'WiFi')
1196 sendChromeMetricsAction('Options_NetworkConnectToWifi');
1197 else if (detailsPage.type_ == 'VPN')
1198 sendChromeMetricsAction('Options_NetworkConnectToVPN');
1200 var onc = detailsPage.onc_;
1201 var guid = onc.guid();
1202 var type = onc.getActiveValue('Type');
1204 // Built-in VPNs do not correctly set 'Connectable', so we always show the
1205 // configuration UI.
1206 if (type == 'VPN') {
1207 if (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') {
1208 chrome.send('configureNetwork', [guid]);
1213 // If 'Connectable' is false for WiFi or WiMAX, Shill requires
1214 // additional configuration to connect, so show the configuration UI.
1215 if ((type == 'WiFi' || type == 'WiMAX') &&
1216 !onc.getActiveValue('Connectable')) {
1217 chrome.send('configureNetwork', [guid]);
1221 // Secure WiFi networks with ErrorState set most likely require
1222 // configuration (e.g. a correct passphrase) before connecting.
1223 if (type == 'WiFi' && onc.getWiFiSecurity() != 'None') {
1224 var errorState = onc.getActiveValue('ErrorState');
1225 if (errorState && errorState != 'Unknown') {
1226 chrome.send('configureNetwork', [guid]);
1231 // Cellular networks need to be activated before they can be connected to.
1232 if (type == 'Cellular') {
1233 var activationState = onc.getActiveValue('Cellular.ActivationState');
1234 if (activationState != 'Activated' && activationState != 'Unknown') {
1235 DetailsInternetPage.activateCellular(guid);
1240 chrome.networkingPrivate.startConnect(guid);
1243 DetailsInternetPage.disconnectNetwork = function() {
1244 var detailsPage = DetailsInternetPage.getInstance();
1245 if (detailsPage.type_ == 'WiFi')
1246 sendChromeMetricsAction('Options_NetworkDisconnectWifi');
1247 else if (detailsPage.type_ == 'VPN')
1248 sendChromeMetricsAction('Options_NetworkDisconnectVPN');
1249 chrome.networkingPrivate.startDisconnect(detailsPage.onc_.guid());
1250 PageManager.closeOverlay();
1253 DetailsInternetPage.configureNetwork = function() {
1254 var detailsPage = DetailsInternetPage.getInstance();
1255 // This is an explicit request to show the configure dialog; do not show
1256 // the enrollment dialog for networks missing a certificate.
1257 var forceShow = true;
1258 chrome.send('configureNetwork', [detailsPage.onc_.guid(), forceShow]);
1259 PageManager.closeOverlay();
1262 DetailsInternetPage.activateFromDetails = function() {
1263 var detailsPage = DetailsInternetPage.getInstance();
1264 if (detailsPage.type_ == 'Cellular')
1265 DetailsInternetPage.activateCellular(detailsPage.onc_.guid());
1266 PageManager.closeOverlay();
1270 * Event handler called when the details page is closed. Sends changed
1271 * properties to Chrome and closes the overlay.
1273 DetailsInternetPage.setDetails = function() {
1274 var detailsPage = DetailsInternetPage.getInstance();
1275 var type = detailsPage.type_;
1276 var oncData = new OncData({});
1277 var autoConnectCheckboxId = '';
1278 if (type == 'WiFi') {
1279 var preferredCheckbox =
1280 assertInstanceof($('prefer-network-wifi'), HTMLInputElement);
1281 if (!preferredCheckbox.hidden && !preferredCheckbox.disabled) {
1282 var kPreferredPriority = 1;
1283 var priority = preferredCheckbox.checked ? kPreferredPriority : 0;
1284 oncData.setProperty('Priority', priority);
1285 sendChromeMetricsAction('Options_NetworkSetPrefer');
1287 autoConnectCheckboxId = 'auto-connect-network-wifi';
1288 } else if (type == 'WiMAX') {
1289 autoConnectCheckboxId = 'auto-connect-network-wimax';
1290 } else if (type == 'Cellular') {
1291 autoConnectCheckboxId = 'auto-connect-network-cellular';
1292 } else if (type == 'VPN') {
1293 var providerType = detailsPage.onc_.getActiveValue('VPN.Type');
1294 if (providerType != 'ThirdPartyVPN') {
1295 oncData.setProperty('VPN.Type', providerType);
1296 oncData.setProperty('VPN.Host', $('inet-server-hostname').value);
1297 autoConnectCheckboxId = 'auto-connect-network-vpn';
1300 if (autoConnectCheckboxId != '') {
1301 var autoConnectCheckbox =
1302 assertInstanceof($(autoConnectCheckboxId), HTMLInputElement);
1303 if (!autoConnectCheckbox.hidden && !autoConnectCheckbox.disabled) {
1304 var autoConnectKey = type + '.AutoConnect';
1305 oncData.setProperty(autoConnectKey, !!autoConnectCheckbox.checked);
1306 sendChromeMetricsAction('Options_NetworkAutoConnect');
1310 var nameServerTypes = ['automatic', 'google', 'user'];
1311 var nameServerType = 'automatic';
1312 for (var i = 0; i < nameServerTypes.length; ++i) {
1313 if ($(nameServerTypes[i] + '-dns-radio').checked) {
1314 nameServerType = nameServerTypes[i];
1318 var ipConfig = detailsPage.getIpConfig_(nameServerType);
1319 var ipAddressType = ('IPAddress' in ipConfig) ? 'Static' : 'DHCP';
1320 var nameServersType = ('NameServers' in ipConfig) ? 'Static' : 'DHCP';
1321 oncData.setProperty('IPAddressConfigType', ipAddressType);
1322 oncData.setProperty('NameServersConfigType', nameServersType);
1323 oncData.setProperty('StaticIPConfig', ipConfig);
1325 var data = oncData.getData();
1326 if (Object.keys(data).length > 0) {
1327 // TODO(stevenjb): Only set changed properties.
1328 chrome.networkingPrivate.setProperties(detailsPage.onc_.guid(), data);
1331 PageManager.closeOverlay();
1335 * Event handler called when the name server type changes.
1336 * @param {string} type The selected name sever type, 'automatic', 'google',
1339 DetailsInternetPage.updateNameServerDisplay = function(type) {
1340 var editable = type == 'user';
1341 var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'),
1342 $('ipconfig-dns3'), $('ipconfig-dns4')];
1343 for (var i = 0; i < fields.length; ++i) {
1344 fields[i].editable = editable;
1347 $('ipconfig-dns1').focus();
1349 var automaticDns = $('automatic-dns-display');
1350 var googleDns = $('google-dns-display');
1351 var userDns = $('user-dns-settings');
1354 automaticDns.setAttribute('selected', '');
1355 googleDns.removeAttribute('selected');
1356 userDns.removeAttribute('selected');
1359 automaticDns.removeAttribute('selected');
1360 googleDns.setAttribute('selected', '');
1361 userDns.removeAttribute('selected');
1364 automaticDns.removeAttribute('selected');
1365 googleDns.removeAttribute('selected');
1366 userDns.setAttribute('selected', '');
1372 * Method called from Chrome when the ONC properties for the displayed
1373 * network may have changed.
1374 * @param {Object} oncData The updated ONC dictionary for the network.
1376 DetailsInternetPage.updateConnectionData = function(oncData) {
1377 var detailsPage = DetailsInternetPage.getInstance();
1378 if (!detailsPage.visible)
1381 if (oncData.GUID != detailsPage.onc_.guid())
1384 // Update our cached data object.
1385 detailsPage.onc_ = new OncData(oncData);
1387 detailsPage.populateHeader_();
1388 detailsPage.updateConnectionButtonVisibility_();
1389 detailsPage.updateDetails_();
1393 * Initializes the details page with the provided ONC data.
1394 * @param {Object} oncData Dictionary of ONC properties.
1396 DetailsInternetPage.initializeDetailsPage = function(oncData) {
1397 var onc = new OncData(oncData);
1399 var detailsPage = DetailsInternetPage.getInstance();
1400 detailsPage.onc_ = onc;
1401 var type = onc.getActiveValue('Type');
1402 detailsPage.type_ = type;
1404 sendShowDetailsMetrics(type, onc.getActiveValue('ConnectionState'));
1406 detailsPage.populateHeader_();
1407 detailsPage.updateConnectionButtonVisibility_();
1408 detailsPage.updateDetails_();
1410 // TODO(stevenjb): Some of the setup below should be moved to
1411 // updateDetails_() so that updates are reflected in the UI.
1413 // Only show proxy for remembered networks.
1414 var remembered = onc.getSource() != 'None';
1416 detailsPage.showProxy_ = true;
1417 // Inform Chrome which network to use for proxy configuration.
1418 chrome.send('selectNetwork', [detailsPage.onc_.guid()]);
1420 detailsPage.showProxy_ = false;
1423 $('web-proxy-auto-discovery').hidden = true;
1425 var restricted = onc.getActiveValue('RestrictedConnectivity');
1426 var restrictedString = loadTimeData.getString(
1427 restricted ? 'restrictedYes' : 'restrictedNo');
1429 // These objects contain an 'automatic' property that is displayed when
1430 // ip-automatic-configuration-checkbox is checked, and a 'value' property
1431 // that is displayed when unchecked and used to set the associated ONC
1432 // property for StaticIPConfig on commit.
1433 var inetAddress = {};
1434 var inetNetmask = {};
1435 var inetGateway = {};
1437 var inetNameServersString;
1439 var ipconfigList = onc.getActiveValue('IPConfigs');
1440 if (Array.isArray(ipconfigList)) {
1441 for (var i = 0; i < ipconfigList.length; ++i) {
1442 var ipconfig = ipconfigList[i];
1443 var ipType = ipconfig['Type'];
1444 if (ipType != 'IPv4') {
1445 // TODO(stevenjb): Handle IPv6 properties.
1448 var address = ipconfig['IPAddress'];
1449 inetAddress.automatic = address;
1450 inetAddress.value = address;
1451 var netmask = prefixLengthToNetmask(ipconfig['RoutingPrefix']);
1452 inetNetmask.automatic = netmask;
1453 inetNetmask.value = netmask;
1454 var gateway = ipconfig['Gateway'];
1455 inetGateway.automatic = gateway;
1456 inetGateway.value = gateway;
1457 if ('WebProxyAutoDiscoveryUrl' in ipconfig) {
1458 $('web-proxy-auto-discovery').hidden = false;
1459 $('web-proxy-auto-discovery-url').value =
1460 ipconfig['WebProxyAutoDiscoveryUrl'];
1462 if ('NameServers' in ipconfig) {
1463 var inetNameServers = ipconfig['NameServers'];
1464 inetNameServers = inetNameServers.sort();
1465 inetNameServersString = inetNameServers.join(',');
1467 break; // Use the first IPv4 entry.
1471 // Override the 'automatic' properties with the saved DHCP values if the
1472 // saved value is set, and set any unset 'value' properties.
1473 var savedNameServersString;
1474 var savedIpAddress = onc.getActiveValue('SavedIPConfig.IPAddress');
1475 if (savedIpAddress != undefined) {
1476 inetAddress.automatic = savedIpAddress;
1477 if (!inetAddress.value)
1478 inetAddress.value = savedIpAddress;
1480 var savedPrefix = onc.getActiveValue('SavedIPConfig.RoutingPrefix');
1481 if (savedPrefix != undefined) {
1482 assert(typeof savedPrefix == 'number');
1483 var savedNetmask = prefixLengthToNetmask(
1484 /** @type {number} */(savedPrefix));
1485 inetNetmask.automatic = savedNetmask;
1486 if (!inetNetmask.value)
1487 inetNetmask.value = savedNetmask;
1489 var savedGateway = onc.getActiveValue('SavedIPConfig.Gateway');
1490 if (savedGateway != undefined) {
1491 inetGateway.automatic = savedGateway;
1492 if (!inetGateway.value)
1493 inetGateway.value = savedGateway;
1496 var savedNameServers = onc.getActiveValue('SavedIPConfig.NameServers');
1497 if (savedNameServers) {
1498 savedNameServers = savedNameServers.sort();
1499 savedNameServersString = savedNameServers.join(',');
1502 var ipAutoConfig = 'automatic';
1503 if (onc.getActiveValue('IPAddressConfigType') == 'Static') {
1504 ipAutoConfig = 'user';
1505 var staticIpAddress = onc.getActiveValue('StaticIPConfig.IPAddress');
1506 inetAddress.user = staticIpAddress;
1507 inetAddress.value = staticIpAddress;
1509 var staticPrefix = onc.getActiveValue('StaticIPConfig.RoutingPrefix');
1510 if (typeof staticPrefix != 'number')
1512 var staticNetmask = prefixLengthToNetmask(
1513 /** @type {number} */ (staticPrefix));
1514 inetNetmask.user = staticNetmask;
1515 inetNetmask.value = staticNetmask;
1517 var staticGateway = onc.getActiveValue('StaticIPConfig.Gateway');
1518 inetGateway.user = staticGateway;
1519 inetGateway.value = staticGateway;
1522 var staticNameServersString;
1523 if (onc.getActiveValue('NameServersConfigType') == 'Static') {
1524 var staticNameServers = onc.getActiveValue('StaticIPConfig.NameServers');
1525 staticNameServers = staticNameServers.sort();
1526 staticNameServersString = staticNameServers.join(',');
1529 $('ip-automatic-configuration-checkbox').checked =
1530 ipAutoConfig == 'automatic';
1532 inetAddress.autoConfig = ipAutoConfig;
1533 inetNetmask.autoConfig = ipAutoConfig;
1534 inetGateway.autoConfig = ipAutoConfig;
1536 var configureAddressField = function(field, model) {
1537 IPAddressField.decorate(field);
1538 field.model = model;
1539 field.editable = model.autoConfig == 'user';
1541 configureAddressField($('ip-address'), inetAddress);
1542 configureAddressField($('ip-netmask'), inetNetmask);
1543 configureAddressField($('ip-gateway'), inetGateway);
1545 // Set Nameserver fields. Nameservers are 'automatic' by default. If a
1546 // static namerserver is set, use that unless it does not match a non
1547 // empty 'NameServers' value (indicating that the custom nameservers are
1548 // invalid or not being applied for some reason). TODO(stevenjb): Only
1549 // set these properites if they change so that invalid custom values do
1551 var nameServerType = 'automatic';
1552 if (staticNameServersString &&
1553 (!inetNameServersString ||
1554 staticNameServersString == inetNameServersString)) {
1555 if (staticNameServersString == GoogleNameServers.join(','))
1556 nameServerType = 'google';
1558 nameServerType = 'user';
1560 if (nameServerType == 'automatic')
1561 $('automatic-dns-display').textContent = inetNameServersString;
1563 $('automatic-dns-display').textContent = savedNameServersString;
1564 $('google-dns-display').textContent = GoogleNameServers.join(',');
1566 var nameServersUser = [];
1567 if (staticNameServers) {
1568 nameServersUser = staticNameServers;
1569 } else if (savedNameServers) {
1570 // Pre-populate with values provided by DHCP server.
1571 nameServersUser = savedNameServers;
1574 var nameServerModels = [];
1575 for (var i = 0; i < 4; ++i)
1576 nameServerModels.push({value: nameServersUser[i] || ''});
1578 $(nameServerType + '-dns-radio').checked = true;
1579 configureAddressField($('ipconfig-dns1'), nameServerModels[0]);
1580 configureAddressField($('ipconfig-dns2'), nameServerModels[1]);
1581 configureAddressField($('ipconfig-dns3'), nameServerModels[2]);
1582 configureAddressField($('ipconfig-dns4'), nameServerModels[3]);
1584 DetailsInternetPage.updateNameServerDisplay(nameServerType);
1586 var macAddress = onc.getActiveValue('MacAddress');
1588 $('hardware-address').textContent = macAddress;
1589 $('hardware-address-row').style.display = 'table-row';
1591 // This is most likely a device without a hardware address.
1592 $('hardware-address-row').style.display = 'none';
1595 var setOrHideParent = function(field, property) {
1596 if (property != undefined) {
1597 $(field).textContent = property;
1598 $(field).parentElement.hidden = false;
1600 $(field).parentElement.hidden = true;
1604 var networkName = onc.getTranslatedValue('Name');
1606 // Signal strength as percentage (for WiFi and WiMAX).
1608 if (type == 'WiFi' || type == 'WiMAX')
1609 signalStrength = onc.getActiveValue(type + '.SignalStrength');
1610 if (!signalStrength)
1612 var strengthFormat = loadTimeData.getString('inetSignalStrengthFormat');
1613 var strengthString = strengthFormat.replace('$1', signalStrength);
1615 if (type == 'WiFi') {
1616 OptionsPage.showTab($('wifi-network-nav-tab'));
1617 $('wifi-restricted-connectivity').textContent = restrictedString;
1618 var ssid = onc.getActiveValue('WiFi.SSID');
1619 $('wifi-ssid').textContent = ssid ? ssid : networkName;
1620 setOrHideParent('wifi-bssid', onc.getActiveValue('WiFi.BSSID'));
1621 var security = onc.getWiFiSecurity();
1622 if (security == 'None')
1623 security = undefined;
1624 setOrHideParent('wifi-security', security);
1625 // Frequency is in MHz.
1626 var frequency = onc.getActiveValue('WiFi.Frequency');
1629 var frequencyFormat = loadTimeData.getString('inetFrequencyFormat');
1630 frequencyFormat = frequencyFormat.replace('$1', frequency);
1631 $('wifi-frequency').textContent = frequencyFormat;
1632 $('wifi-signal-strength').textContent = strengthString;
1633 setOrHideParent('wifi-hardware-address',
1634 onc.getActiveValue('MacAddress'));
1635 var priority = onc.getActiveValue('Priority');
1636 $('prefer-network-wifi').checked = priority > 0;
1637 $('prefer-network-wifi').disabled = !remembered;
1638 $('auto-connect-network-wifi').checked =
1639 onc.getActiveValue('WiFi.AutoConnect');
1640 $('auto-connect-network-wifi').disabled = !remembered;
1641 } else if (type == 'WiMAX') {
1642 OptionsPage.showTab($('wimax-network-nav-tab'));
1643 $('wimax-restricted-connectivity').textContent = restrictedString;
1645 $('auto-connect-network-wimax').checked =
1646 onc.getActiveValue('WiMAX.AutoConnect');
1647 $('auto-connect-network-wimax').disabled = !remembered;
1648 var identity = onc.getActiveValue('WiMAX.EAP.Identity');
1649 setOrHideParent('wimax-eap-identity', identity);
1650 $('wimax-signal-strength').textContent = strengthString;
1651 } else if (type == 'Cellular') {
1652 OptionsPage.showTab($('cellular-conn-nav-tab'));
1654 var isGsm = onc.getActiveValue('Cellular.Family') == 'GSM';
1656 $('service-name').textContent = networkName;
1658 // TODO(stevenjb): Ideally many of these should be localized.
1659 $('network-technology').textContent =
1660 onc.getActiveValue('Cellular.NetworkTechnology');
1661 $('roaming-state').textContent =
1662 onc.getTranslatedValue('Cellular.RoamingState');
1663 $('cellular-restricted-connectivity').textContent = restrictedString;
1664 $('error-state').textContent = onc.getActiveValue('ErrorState');
1665 $('manufacturer').textContent =
1666 onc.getActiveValue('Cellular.Manufacturer');
1667 $('model-id').textContent = onc.getActiveValue('Cellular.ModelID');
1668 $('firmware-revision').textContent =
1669 onc.getActiveValue('Cellular.FirmwareRevision');
1670 $('hardware-revision').textContent =
1671 onc.getActiveValue('Cellular.HardwareRevision');
1672 $('mdn').textContent = onc.getActiveValue('Cellular.MDN');
1674 // Show ServingOperator properties only if available.
1675 var servingOperatorName =
1676 onc.getActiveValue('Cellular.ServingOperator.Name');
1677 var servingOperatorCode =
1678 onc.getActiveValue('Cellular.ServingOperator.Code');
1679 if (servingOperatorName != undefined &&
1680 servingOperatorCode != undefined) {
1681 $('operator-name').textContent = servingOperatorName;
1682 $('operator-code').textContent = servingOperatorCode;
1684 $('operator-name').parentElement.hidden = true;
1685 $('operator-code').parentElement.hidden = true;
1687 // Make sure that GSM/CDMA specific properties that shouldn't be hidden
1689 updateHidden('#details-internet-page .gsm-only', false);
1690 updateHidden('#details-internet-page .cdma-only', false);
1692 // Show IMEI/ESN/MEID/MIN/PRL only if they are available.
1693 setOrHideParent('esn', onc.getActiveValue('Cellular.ESN'));
1694 setOrHideParent('imei', onc.getActiveValue('Cellular.IMEI'));
1695 setOrHideParent('meid', onc.getActiveValue('Cellular.MEID'));
1696 setOrHideParent('min', onc.getActiveValue('Cellular.MIN'));
1697 setOrHideParent('prl-version', onc.getActiveValue('Cellular.PRLVersion'));
1700 $('iccid').textContent = onc.getActiveValue('Cellular.ICCID');
1701 $('imsi').textContent = onc.getActiveValue('Cellular.IMSI');
1702 detailsPage.initializeApnList_();
1704 $('auto-connect-network-cellular').checked =
1705 onc.getActiveValue('Cellular.AutoConnect');
1706 $('auto-connect-network-cellular').disabled = false;
1707 } else if (type == 'VPN') {
1708 OptionsPage.showTab($('vpn-nav-tab'));
1709 var providerType = onc.getActiveValue('VPN.Type');
1710 var isThirdPartyVPN = providerType == 'ThirdPartyVPN';
1711 $('vpn-tab').classList.toggle('third-party-vpn-provider',
1714 $('inet-service-name').textContent = networkName;
1715 $('inet-provider-type').textContent =
1716 onc.getTranslatedValue('VPN.Type');
1718 if (isThirdPartyVPN) {
1719 $('inet-provider-name').textContent =
1720 onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName');
1723 if (providerType == 'OpenVPN')
1724 usernameKey = 'VPN.OpenVPN.Username';
1725 else if (providerType == 'L2TP-IPsec')
1726 usernameKey = 'VPN.L2TP.Username';
1729 $('inet-username').parentElement.hidden = false;
1730 $('inet-username').textContent = onc.getActiveValue(usernameKey);
1732 $('inet-username').parentElement.hidden = true;
1734 var inetServerHostname = $('inet-server-hostname');
1735 inetServerHostname.value = onc.getActiveValue('VPN.Host');
1736 inetServerHostname.resetHandler = function() {
1737 PageManager.hideBubble();
1738 var recommended = onc.getRecommendedValue('VPN.Host');
1739 if (recommended != undefined)
1740 inetServerHostname.value = recommended;
1742 $('auto-connect-network-vpn').checked =
1743 onc.getActiveValue('VPN.AutoConnect');
1744 $('auto-connect-network-vpn').disabled = false;
1747 OptionsPage.showTab($('internet-nav-tab'));
1750 // Update controlled option indicators.
1751 var indicators = cr.doc.querySelectorAll(
1752 '#details-internet-page .controlled-setting-indicator');
1753 for (var i = 0; i < indicators.length; i++) {
1754 var managed = indicators[i].hasAttribute('managed');
1755 // TODO(stevenjb): Eliminate support for 'data' once 39 is stable.
1756 var attributeName = managed ? 'managed' : 'data';
1757 var propName = indicators[i].getAttribute(attributeName);
1760 var propValue = managed ?
1761 onc.getManagedProperty(propName) :
1762 onc.getActiveValue(propName);
1763 // If the property is unset or unmanaged (i.e. not an Object) skip it.
1764 if (propValue == undefined || (typeof propValue != 'object'))
1768 event = detailsPage.createManagedEvent_(propName, propValue);
1770 event = detailsPage.createControlledEvent_(propName,
1771 /** @type {{value: *, controlledBy: *, recommendedValue: *}} */(
1773 indicators[i].handlePrefChange(event);
1774 var forElement = $(indicators[i].getAttribute('internet-detail-for'));
1776 if (event.value.controlledBy == 'policy')
1777 forElement.disabled = true;
1778 if (forElement.resetHandler)
1779 indicators[i].resetHandler = forElement.resetHandler;
1783 detailsPage.updateControls();
1785 // Don't show page name in address bar and in history to prevent people
1786 // navigate here by hand and solve issue with page session restore.
1787 PageManager.showPageByName('detailsInternetPage', false);
1791 DetailsInternetPage: DetailsInternetPage