| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // require: onc_data.js |
| |
| // NOTE(stevenjb): This code is in the process of being converted to be |
| // compatible with the networkingPrivate extension API: |
| // * The network property dictionaries are being converted to use ONC values. |
| // * chrome.send calls will be replaced with chrome.networkingPrivate calls. |
| // See crbug.com/279351 for more info. |
| |
| cr.define('options.internet', function() { |
| var OncData = cr.onc.OncData; |
| var Page = cr.ui.pageManager.Page; |
| var PageManager = cr.ui.pageManager.PageManager; |
| /** @const */ var IPAddressField = options.internet.IPAddressField; |
| |
| /** @const */ var GoogleNameServers = ['8.8.4.4', '8.8.8.8']; |
| /** @const */ var CarrierSprint = 'Sprint'; |
| /** @const */ var CarrierVerizon = 'Verizon Wireless'; |
| |
| /** |
| * Helper function to set hidden attribute for elements matching a selector. |
| * @param {string} selector CSS selector for extracting a list of elements. |
| * @param {boolean} hidden New hidden value. |
| */ |
| function updateHidden(selector, hidden) { |
| var elements = cr.doc.querySelectorAll(selector); |
| for (var i = 0, el; el = elements[i]; i++) { |
| el.hidden = hidden; |
| } |
| } |
| |
| /** |
| * Helper function to update the properties of the data object from the |
| * properties in the update object. |
| * @param {Object} data Object to update. |
| * @param {Object} update Object containing the updated properties. |
| */ |
| function updateDataObject(data, update) { |
| for (var prop in update) { |
| if (prop in data) |
| data[prop] = update[prop]; |
| } |
| } |
| |
| /** |
| * Monitor pref change of given element. |
| * @param {Element} el Target element. |
| */ |
| function observePrefsUI(el) { |
| Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate); |
| } |
| |
| /** |
| * UI pref change handler. |
| * @param {Event} e The update event. |
| */ |
| function handlePrefUpdate(e) { |
| DetailsInternetPage.getInstance().updateControls(); |
| } |
| |
| /** |
| * Simple helper method for converting a field to a string. It is used to |
| * easily assign an empty string from fields that may be unknown or undefined. |
| * @param {Object} value that should be converted to a string. |
| * @return {string} the result. |
| */ |
| function stringFromValue(value) { |
| return value ? String(value) : ''; |
| } |
| |
| /** |
| * @param {string} action An action to send to coreOptionsUserMetricsAction. |
| */ |
| function sendChromeMetricsAction(action) { |
| chrome.send('coreOptionsUserMetricsAction', [action]); |
| } |
| |
| /** |
| * Send metrics to Chrome when the detailed page is opened. |
| * @param {string} type The ONC type of the network being shown. |
| * @param {string} state The ONC network state. |
| */ |
| function sendShowDetailsMetrics(type, state) { |
| if (type == 'WiFi') { |
| sendChromeMetricsAction('Options_NetworkShowDetailsWifi'); |
| if (state != 'NotConnected') |
| sendChromeMetricsAction('Options_NetworkShowDetailsWifiConnected'); |
| } else if (type == 'Cellular') { |
| sendChromeMetricsAction('Options_NetworkShowDetailsCellular'); |
| if (state != 'NotConnected') |
| sendChromeMetricsAction('Options_NetworkShowDetailsCellularConnected'); |
| } else if (type == 'VPN') { |
| sendChromeMetricsAction('Options_NetworkShowDetailsVPN'); |
| if (state != 'NotConnected') |
| sendChromeMetricsAction('Options_NetworkShowDetailsVPNConnected'); |
| } |
| } |
| |
| /** |
| * Returns the netmask as a string for a given prefix length. |
| * @param {number} prefixLength The ONC routing prefix length. |
| * @return {string} The corresponding netmask. |
| */ |
| function prefixLengthToNetmask(prefixLength) { |
| // Return the empty string for invalid inputs. |
| if (prefixLength < 0 || prefixLength > 32) |
| return ''; |
| var netmask = ''; |
| for (var i = 0; i < 4; ++i) { |
| var remainder = 8; |
| if (prefixLength >= 8) { |
| prefixLength -= 8; |
| } else { |
| remainder = prefixLength; |
| prefixLength = 0; |
| } |
| if (i > 0) |
| netmask += '.'; |
| var value = 0; |
| if (remainder != 0) |
| value = ((2 << (remainder - 1)) - 1) << (8 - remainder); |
| netmask += value.toString(); |
| } |
| return netmask; |
| } |
| |
| /** |
| * Returns the prefix length from the netmask string. |
| * @param {string} netmask The netmask string, e.g. 255.255.255.0. |
| * @return {number} The corresponding netmask or -1 if invalid. |
| */ |
| function netmaskToPrefixLength(netmask) { |
| var prefixLength = 0; |
| var tokens = netmask.split('.'); |
| if (tokens.length != 4) |
| return -1; |
| for (var i = 0; i < tokens.length; ++i) { |
| var token = tokens[i]; |
| // If we already found the last mask and the current one is not |
| // '0' then the netmask is invalid. For example, 255.224.255.0 |
| if (prefixLength / 8 != i) { |
| if (token != '0') |
| return -1; |
| } else if (token == '255') { |
| prefixLength += 8; |
| } else if (token == '254') { |
| prefixLength += 7; |
| } else if (token == '252') { |
| prefixLength += 6; |
| } else if (token == '248') { |
| prefixLength += 5; |
| } else if (token == '240') { |
| prefixLength += 4; |
| } else if (token == '224') { |
| prefixLength += 3; |
| } else if (token == '192') { |
| prefixLength += 2; |
| } else if (token == '128') { |
| prefixLength += 1; |
| } else if (token == '0') { |
| prefixLength += 0; |
| } else { |
| // mask is not a valid number. |
| return -1; |
| } |
| } |
| return prefixLength; |
| } |
| |
| // Returns true if we should show the 'View Account' button for |onc|. |
| // TODO(stevenjb): We should query the Mobile Config API for whether or not to |
| // show the 'View Account' button once it is integrated with Settings. |
| function shouldShowViewAccountButton(onc) { |
| var activationState = onc.getActiveValue('Cellular.ActivationState'); |
| if (activationState != 'Activating' && activationState != 'Activated') |
| return false; |
| |
| // If no online payment URL was provided by Shill, only show 'View Account' |
| // for Verizon Wireless. |
| if (!onc.getActiveValue('Cellular.PaymentPortal.Url') && |
| onc.getActiveValue('Cellular.Carrier') != CarrierVerizon) { |
| return false; |
| } |
| |
| // 'View Account' should only be shown for connected networks, or |
| // disconnected LTE networks with a valid MDN. |
| var connectionState = onc.getActiveValue('ConnectionState'); |
| if (connectionState != 'Connected') { |
| var technology = onc.getActiveValue('Cellular.NetworkTechnology'); |
| if (technology != 'LTE' && technology != 'LTEAdvanced') |
| return false; |
| if (!onc.getActiveValue('Cellular.MDN')) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // DetailsInternetPage class: |
| |
| /** |
| * Encapsulated handling of ChromeOS internet details overlay page. |
| * @constructor |
| * @extends {cr.ui.pageManager.Page} |
| */ |
| function DetailsInternetPage() { |
| // If non-negative, indicates a custom entry in select-apn. |
| this.userApnIndex_ = -1; |
| |
| // The custom APN properties associated with entry |userApnIndex_|. |
| this.userApn_ = {}; |
| |
| // The currently selected APN entry in $('select-apn') (which may or may not |
| // == userApnIndex_). |
| this.selectedApnIndex_ = -1; |
| |
| // We show the Proxy configuration tab for remembered networks and when |
| // configuring a proxy from the login screen. |
| this.showProxy_ = false; |
| |
| Page.call(this, 'detailsInternetPage', '', 'details-internet-page'); |
| } |
| |
| cr.addSingletonGetter(DetailsInternetPage); |
| |
| DetailsInternetPage.prototype = { |
| __proto__: Page.prototype, |
| |
| /** @override */ |
| initializePage: function() { |
| Page.prototype.initializePage.call(this); |
| this.initializePageContents_(); |
| |
| chrome.networkingPrivate.onNetworksChanged.addListener( |
| this.onNetworksChanged_.bind(this)); |
| |
| this.showNetworkDetails_(); |
| }, |
| |
| /** |
| * Automatically shows the network details dialog if network information |
| * is included in the URL. |
| */ |
| showNetworkDetails_: function() { |
| var guid = parseQueryParams(window.location).guid; |
| if (!guid || !guid.length) |
| return; |
| chrome.networkingPrivate.getManagedProperties( |
| guid, DetailsInternetPage.initializeDetailsPage); |
| }, |
| |
| /** |
| * networkingPrivate callback when networks change. |
| * @param {Array<string>} changes List of GUIDs whose properties have |
| * changed. |
| * @private |
| */ |
| onNetworksChanged_: function(changes) { |
| if (!this.onc_) |
| return; |
| var guid = this.onc_.guid(); |
| if (changes.indexOf(guid) != -1) { |
| chrome.networkingPrivate.getManagedProperties( |
| guid, DetailsInternetPage.updateConnectionData); |
| } |
| }, |
| |
| /** |
| * Initializes the contents of the page. |
| */ |
| initializePageContents_: function() { |
| $('details-internet-dismiss').addEventListener('click', function(event) { |
| DetailsInternetPage.setDetails(); |
| }); |
| |
| $('details-internet-login').addEventListener('click', function(event) { |
| DetailsInternetPage.setDetails(); |
| DetailsInternetPage.loginFromDetails(); |
| }); |
| |
| $('details-internet-disconnect').addEventListener('click', |
| function(event) { |
| DetailsInternetPage.setDetails(); |
| DetailsInternetPage.disconnectNetwork(); |
| }); |
| |
| $('details-internet-configure').addEventListener('click', |
| function(event) { |
| DetailsInternetPage.setDetails(); |
| DetailsInternetPage.configureNetwork(); |
| }); |
| |
| $('activate-details').addEventListener('click', function(event) { |
| DetailsInternetPage.activateFromDetails(); |
| }); |
| |
| $('view-account-details').addEventListener('click', function(event) { |
| chrome.send('showMorePlanInfo', |
| [DetailsInternetPage.getInstance().onc_.guid()]); |
| PageManager.closeOverlay(); |
| }); |
| |
| $('cellular-apn-use-default').addEventListener('click', function(event) { |
| DetailsInternetPage.getInstance().setDefaultApn_(); |
| }); |
| |
| $('cellular-apn-set').addEventListener('click', function(event) { |
| DetailsInternetPage.getInstance().setApn_($('cellular-apn').value); |
| }); |
| |
| $('cellular-apn-cancel').addEventListener('click', function(event) { |
| DetailsInternetPage.getInstance().cancelApn_(); |
| }); |
| |
| $('select-apn').addEventListener('change', function(event) { |
| DetailsInternetPage.getInstance().selectApn_(); |
| }); |
| |
| $('sim-card-lock-enabled').addEventListener('click', function(event) { |
| var newValue = $('sim-card-lock-enabled').checked; |
| // Leave value as is because user needs to enter PIN code first. |
| // When PIN will be entered and value changed, |
| // we'll update UI to reflect that change. |
| $('sim-card-lock-enabled').checked = !newValue; |
| var operation = newValue ? 'setLocked' : 'setUnlocked'; |
| chrome.send('simOperation', [operation]); |
| }); |
| $('change-pin').addEventListener('click', function(event) { |
| chrome.send('simOperation', ['changePin']); |
| }); |
| |
| // Proxy |
| ['proxy-host-single-port', |
| 'secure-proxy-port', |
| 'socks-port', |
| 'ftp-proxy-port', |
| 'proxy-host-port' |
| ].forEach(function(id) { |
| options.PrefPortNumber.decorate($(id)); |
| }); |
| |
| options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list')); |
| $('remove-host').addEventListener('click', |
| this.handleRemoveProxyExceptions_); |
| $('add-host').addEventListener('click', this.handleAddProxyException_); |
| $('direct-proxy').addEventListener('click', this.disableManualProxy_); |
| $('manual-proxy').addEventListener('click', this.enableManualProxy_); |
| $('auto-proxy').addEventListener('click', this.disableManualProxy_); |
| $('proxy-all-protocols').addEventListener('click', |
| this.toggleSingleProxy_); |
| $('proxy-use-pac-url').addEventListener('change', |
| this.handleAutoConfigProxy_); |
| |
| observePrefsUI($('direct-proxy')); |
| observePrefsUI($('manual-proxy')); |
| observePrefsUI($('auto-proxy')); |
| observePrefsUI($('proxy-all-protocols')); |
| observePrefsUI($('proxy-use-pac-url')); |
| |
| $('ip-automatic-configuration-checkbox').addEventListener('click', |
| this.handleIpAutoConfig_); |
| $('automatic-dns-radio').addEventListener('click', |
| this.handleNameServerTypeChange_); |
| $('google-dns-radio').addEventListener('click', |
| this.handleNameServerTypeChange_); |
| $('user-dns-radio').addEventListener('click', |
| this.handleNameServerTypeChange_); |
| |
| // We only load this string if we have the string data available |
| // because the proxy settings page on the login screen re-uses the |
| // proxy sub-page from the internet options, and it doesn't ever |
| // show the DNS settings, so we don't need this string there. |
| // The string isn't available because |
| // chrome://settings-frame/strings.js (where the string is |
| // stored) is not accessible from the login screen. |
| // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login |
| // page is fixed. http://crbug.com/242865 |
| if (loadTimeData.data_) { |
| $('google-dns-label').innerHTML = |
| loadTimeData.getString('googleNameServers'); |
| } |
| }, |
| |
| /** |
| * Handler for "add" event fired from userNameEdit. |
| * @param {Event} e Add event fired from userNameEdit. |
| * @private |
| */ |
| handleAddProxyException_: function(e) { |
| var exception = $('new-host').value; |
| $('new-host').value = ''; |
| |
| exception = exception.trim(); |
| if (exception) |
| $('ignored-host-list').addException(exception); |
| }, |
| |
| /** |
| * Handler for when the remove button is clicked |
| * @param {Event} e The click event. |
| * @private |
| */ |
| handleRemoveProxyExceptions_: function(e) { |
| var selectedItems = $('ignored-host-list').selectedItems; |
| for (var x = 0; x < selectedItems.length; x++) { |
| $('ignored-host-list').removeException(selectedItems[x]); |
| } |
| }, |
| |
| /** |
| * Handler for when the IP automatic configuration checkbox is clicked. |
| * @param {Event} e The click event. |
| * @private |
| */ |
| handleIpAutoConfig_: function(e) { |
| var checked = $('ip-automatic-configuration-checkbox').checked; |
| var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')]; |
| for (var i = 0; i < fields.length; ++i) { |
| fields[i].editable = !checked; |
| if (checked) { |
| var model = fields[i].model; |
| model.value = model.automatic; |
| fields[i].model = model; |
| } |
| } |
| if (!checked) |
| $('ip-address').focus(); |
| }, |
| |
| /** |
| * Handler for when the name server selection changes. |
| * @param {Event} event The click event. |
| * @private |
| */ |
| handleNameServerTypeChange_: function(event) { |
| var type = event.target.value; |
| DetailsInternetPage.updateNameServerDisplay(type); |
| }, |
| |
| /** |
| * Gets the IPConfig ONC Object. |
| * @param {string} nameServerType The selected name server type: |
| * 'automatic', 'google', or 'user'. |
| * @return {Object} The IPConfig ONC object. |
| * @private |
| */ |
| getIpConfig_: function(nameServerType) { |
| var ipConfig = {}; |
| // If 'ip-address' is empty, automatic configuration will be used. |
| if (!$('ip-automatic-configuration-checkbox').checked && |
| $('ip-address').model.value) { |
| ipConfig['IPAddress'] = $('ip-address').model.value; |
| var netmask = $('ip-netmask').model.value; |
| var routingPrefix = 0; |
| if (netmask) { |
| routingPrefix = netmaskToPrefixLength(netmask); |
| if (routingPrefix == -1) { |
| console.error('Invalid netmask: ' + netmask); |
| routingPrefix = 0; |
| } |
| } |
| ipConfig['RoutingPrefix'] = routingPrefix; |
| ipConfig['Gateway'] = $('ip-gateway').model.value || ''; |
| } |
| |
| // Note: If no nameserver fields are set, automatic configuration will be |
| // used. TODO(stevenjb): Validate input fields. |
| if (nameServerType != 'automatic') { |
| var userNameServers = []; |
| if (nameServerType == 'google') { |
| userNameServers = GoogleNameServers.slice(); |
| } else if (nameServerType == 'user') { |
| for (var i = 1; i <= 4; ++i) { |
| var nameServerField = $('ipconfig-dns' + i); |
| // Skip empty values. |
| if (nameServerField && nameServerField.model && |
| nameServerField.model.value) { |
| userNameServers.push(nameServerField.model.value); |
| } |
| } |
| } |
| if (userNameServers.length) |
| ipConfig['NameServers'] = userNameServers.sort(); |
| } |
| return ipConfig; |
| }, |
| |
| /** |
| * Creates an indicator event for controlled properties using |
| * the same dictionary format as CoreOptionsHandler::CreateValueForPref. |
| * @param {string} name The name for the Event. |
| * @param {{value: *, controlledBy: *, recommendedValue: *}} propData |
| * Property dictionary. |
| * @private |
| */ |
| createControlledEvent_: function(name, propData) { |
| assert('value' in propData && 'controlledBy' in propData && |
| 'recommendedValue' in propData); |
| var event = new Event(name); |
| event.value = { |
| value: propData.value, |
| controlledBy: propData.controlledBy, |
| recommendedValue: propData.recommendedValue |
| }; |
| return event; |
| }, |
| |
| /** |
| * Creates an indicator event for controlled properties using |
| * the ONC getManagedProperties dictionary format. |
| * @param {string} name The name for the Event. |
| * @param {Object} propData ONC managed network property dictionary. |
| * @private |
| */ |
| createManagedEvent_: function(name, propData) { |
| var event = new Event(name); |
| event.value = {}; |
| |
| // Set the current value and recommended value. |
| var activeValue = propData['Active']; |
| var effective = propData['Effective']; |
| if (activeValue == undefined) |
| activeValue = propData[effective]; |
| event.value.value = activeValue; |
| |
| // If a property is editable then it is not enforced, and 'controlledBy' |
| // is set to 'recommended' unless effective == {User|Shared}Setting, in |
| // which case the value was modified from the recommended value. |
| // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then |
| // the set value is mandated by the policy. |
| if (propData['UserEditable']) { |
| if (effective == 'UserPolicy') |
| event.value.controlledBy = 'recommended'; |
| event.value.recommendedValue = propData['UserPolicy']; |
| } else if (propData['DeviceEditable']) { |
| if (effective == 'DevicePolicy') |
| event.value.controlledBy = 'recommended'; |
| event.value.recommendedValue = propData['DevicePolicy']; |
| } else if (effective == 'UserPolicy' || effective == 'DevicePolicy') { |
| event.value.controlledBy = 'policy'; |
| } |
| |
| return event; |
| }, |
| |
| /** |
| * Update details page controls. |
| */ |
| updateControls: function() { |
| // Note: onc may be undefined when called from a pref update before |
| // initialized in initializeDetailsPage. |
| var onc = this.onc_; |
| |
| // Always show the ipconfig section. TODO(stevenjb): Improve the display |
| // for unconnected networks. Currently the IP address fields may be |
| // blank if the network is not connected. |
| $('ipconfig-section').hidden = false; |
| $('ipconfig-dns-section').hidden = false; |
| |
| // Network type related. |
| updateHidden('#details-internet-page .cellular-details', |
| this.type_ != 'Cellular'); |
| updateHidden('#details-internet-page .wifi-details', |
| this.type_ != 'WiFi'); |
| updateHidden('#details-internet-page .wimax-details', |
| this.type_ != 'WiMAX'); |
| updateHidden('#details-internet-page .vpn-details', this.type_ != 'VPN'); |
| updateHidden('#details-internet-page .proxy-details', !this.showProxy_); |
| |
| // Cellular |
| if (onc && this.type_ == 'Cellular') { |
| // Hide gsm/cdma specific elements. |
| if (onc.getActiveValue('Cellular.Family') == 'GSM') |
| updateHidden('#details-internet-page .cdma-only', true); |
| else |
| updateHidden('#details-internet-page .gsm-only', true); |
| } |
| |
| // Wifi |
| |
| // Hide network tab for VPN. |
| updateHidden('#details-internet-page .network-details', |
| this.type_ == 'VPN'); |
| |
| // Password and shared. |
| var source = onc ? onc.getSource() : 'None'; |
| var shared = (source == 'Device' || source == 'DevicePolicy'); |
| var security = onc ? onc.getWiFiSecurity() : 'None'; |
| updateHidden('#details-internet-page #password-details', |
| this.type_ != 'WiFi' || security == 'None'); |
| updateHidden('#details-internet-page #wifi-shared-network', !shared); |
| updateHidden('#details-internet-page #prefer-network', source == 'None'); |
| |
| // WiMAX. |
| updateHidden('#details-internet-page #wimax-shared-network', !shared); |
| |
| // Proxy |
| this.updateProxyBannerVisibility_(); |
| this.toggleSingleProxy_(); |
| if ($('manual-proxy').checked) |
| this.enableManualProxy_(); |
| else |
| this.disableManualProxy_(); |
| }, |
| |
| /** |
| * Updates info banner visibility state. This function shows the banner |
| * if proxy is managed or shared-proxies is off for shared network. |
| * @private |
| */ |
| updateProxyBannerVisibility_: function() { |
| var bannerDiv = $('network-proxy-info-banner'); |
| if (!loadTimeData.data_) { |
| // TODO(pneubeck): This temporarily prevents an exception below until |
| // i18n of the proxy dialog on the login page is |
| // fixed. http://crbug.com/242865 |
| bannerDiv.hidden = true; |
| return; |
| } |
| |
| // Show banner and determine its message if necessary. |
| var controlledBy = $('direct-proxy').controlledBy; |
| if (!controlledBy || controlledBy == '') { |
| bannerDiv.hidden = true; |
| } else { |
| bannerDiv.hidden = false; |
| // The possible banner texts are loaded in proxy_handler.cc. |
| var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() + |
| controlledBy.slice(1); |
| $('banner-text').textContent = loadTimeData.getString(bannerText); |
| } |
| }, |
| |
| /** |
| * Handler for when the user clicks on the checkbox to allow a |
| * single proxy usage. |
| * @private |
| */ |
| toggleSingleProxy_: function() { |
| if ($('proxy-all-protocols').checked) { |
| $('multi-proxy').hidden = true; |
| $('single-proxy').hidden = false; |
| } else { |
| $('multi-proxy').hidden = false; |
| $('single-proxy').hidden = true; |
| } |
| }, |
| |
| /** |
| * Handler for when the user clicks on the checkbox to enter |
| * auto configuration URL. |
| * @private |
| */ |
| handleAutoConfigProxy_: function() { |
| $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked; |
| }, |
| |
| /** |
| * Handler for selecting a radio button that will disable the manual |
| * controls. |
| * @private |
| */ |
| disableManualProxy_: function() { |
| $('ignored-host-list').disabled = true; |
| $('new-host').disabled = true; |
| $('remove-host').disabled = true; |
| $('add-host').disabled = true; |
| $('proxy-all-protocols').disabled = true; |
| $('proxy-host-name').disabled = true; |
| $('proxy-host-port').disabled = true; |
| $('proxy-host-single-name').disabled = true; |
| $('proxy-host-single-port').disabled = true; |
| $('secure-proxy-host-name').disabled = true; |
| $('secure-proxy-port').disabled = true; |
| $('ftp-proxy').disabled = true; |
| $('ftp-proxy-port').disabled = true; |
| $('socks-host').disabled = true; |
| $('socks-port').disabled = true; |
| $('proxy-use-pac-url').disabled = $('auto-proxy').disabled || |
| !$('auto-proxy').checked; |
| $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled || |
| !$('proxy-use-pac-url').checked; |
| $('auto-proxy-parms').hidden = !$('auto-proxy').checked; |
| $('manual-proxy-parms').hidden = !$('manual-proxy').checked; |
| sendChromeMetricsAction('Options_NetworkManualProxy_Disable'); |
| }, |
| |
| /** |
| * Handler for selecting a radio button that will enable the manual |
| * controls. |
| * @private |
| */ |
| enableManualProxy_: function() { |
| $('ignored-host-list').redraw(); |
| var allDisabled = $('manual-proxy').disabled; |
| $('ignored-host-list').disabled = allDisabled; |
| $('new-host').disabled = allDisabled; |
| $('remove-host').disabled = allDisabled; |
| $('add-host').disabled = allDisabled; |
| $('proxy-all-protocols').disabled = allDisabled; |
| $('proxy-host-name').disabled = allDisabled; |
| $('proxy-host-port').disabled = allDisabled; |
| $('proxy-host-single-name').disabled = allDisabled; |
| $('proxy-host-single-port').disabled = allDisabled; |
| $('secure-proxy-host-name').disabled = allDisabled; |
| $('secure-proxy-port').disabled = allDisabled; |
| $('ftp-proxy').disabled = allDisabled; |
| $('ftp-proxy-port').disabled = allDisabled; |
| $('socks-host').disabled = allDisabled; |
| $('socks-port').disabled = allDisabled; |
| $('proxy-use-pac-url').disabled = true; |
| $('proxy-pac-url').disabled = true; |
| $('auto-proxy-parms').hidden = !$('auto-proxy').checked; |
| $('manual-proxy-parms').hidden = !$('manual-proxy').checked; |
| sendChromeMetricsAction('Options_NetworkManualProxy_Enable'); |
| }, |
| |
| /** |
| * Helper method called from initializeDetailsPage and updateConnectionData. |
| * Updates visibility/enabled of the login/disconnect/configure buttons. |
| * @private |
| */ |
| updateConnectionButtonVisibility_: function() { |
| var onc = this.onc_; |
| |
| var prohibitedByPolicy = |
| this.type_ == 'WiFi' && |
| loadTimeData.valueExists('allowOnlyPolicyNetworksToConnect') && |
| loadTimeData.getBoolean('allowOnlyPolicyNetworksToConnect') && |
| (onc.data_.Source != 'DevicePolicy' && |
| onc.data_.Source != 'UserPolicy'); |
| |
| if (this.type_ == 'Ethernet') { |
| // Ethernet can never be connected or disconnected and can always be |
| // configured (e.g. to set security). |
| $('details-internet-login').hidden = true; |
| $('details-internet-disconnect').hidden = true; |
| $('details-internet-configure').hidden = false; |
| return; |
| } |
| |
| var connectable = onc.getActiveValue('Connectable'); |
| var connectState = onc.getActiveValue('ConnectionState'); |
| if (connectState == 'NotConnected') { |
| $('details-internet-disconnect').hidden = true; |
| $('details-internet-login').hidden = false; |
| // Connecting to an unconfigured network might trigger certificate |
| // installation UI. Until that gets handled here, always enable the |
| // Connect button for built-in networks. |
| var enabled = ((this.type_ != 'VPN') || |
| (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') || |
| connectable) && !prohibitedByPolicy; |
| if (prohibitedByPolicy) { |
| $('details-internet-login').setAttribute( |
| 'title', loadTimeData.getString('prohibitedNetwork')); |
| } else { |
| $('details-internet-login').removeAttribute('title'); |
| } |
| $('details-internet-login').disabled = !enabled; |
| } else { |
| $('details-internet-login').hidden = true; |
| $('details-internet-disconnect').hidden = false; |
| } |
| |
| var showConfigure = false; |
| if (this.type_ == 'VPN') { |
| showConfigure = true; |
| } else if (this.type_ == 'WiMAX' && connectState == 'NotConnected') { |
| showConfigure = true; |
| } else if (this.type_ == 'WiFi') { |
| showConfigure = (connectState == 'NotConnected' && |
| (!connectable || onc.getWiFiSecurity() != 'None') && |
| !prohibitedByPolicy); |
| } |
| $('details-internet-configure').hidden = !showConfigure; |
| }, |
| |
| /** |
| * Helper method called from initializeDetailsPage and updateConnectionData. |
| * Updates the connection state property and account / sim card links. |
| * @private |
| */ |
| updateDetails_: function() { |
| var onc = this.onc_; |
| |
| var connectionStateString = onc.getTranslatedValue('ConnectionState'); |
| $('connection-state').textContent = connectionStateString; |
| |
| var type = this.type_; |
| var showViewAccount = false; |
| var showActivate = false; |
| if (type == 'WiFi') { |
| $('wifi-connection-state').textContent = connectionStateString; |
| } else if (type == 'WiMAX') { |
| $('wimax-connection-state').textContent = connectionStateString; |
| } else if (type == 'Cellular') { |
| $('activation-state').textContent = |
| onc.getTranslatedValue('Cellular.ActivationState'); |
| if (onc.getActiveValue('Cellular.Family') == 'GSM') { |
| var lockEnabled = |
| onc.getActiveValue('Cellular.SIMLockStatus.LockEnabled'); |
| $('sim-card-lock-enabled').checked = lockEnabled; |
| $('change-pin').hidden = !lockEnabled; |
| } |
| showViewAccount = shouldShowViewAccountButton(onc); |
| var activationState = onc.getActiveValue('Cellular.ActivationState'); |
| showActivate = (activationState == 'NotActivated' || |
| activationState == 'PartiallyActivated'); |
| } |
| |
| $('view-account-details').hidden = !showViewAccount; |
| $('activate-details').hidden = !showActivate; |
| // If activation is not complete, hide the login button. |
| if (showActivate) |
| $('details-internet-login').hidden = true; |
| }, |
| |
| /** |
| * Helper method called from initializeDetailsPage and updateConnectionData. |
| * Updates the fields in the header section of the details frame. |
| * @private |
| */ |
| populateHeader_: function() { |
| var onc = this.onc_; |
| |
| var name = onc.getTranslatedValue('Name'); |
| if (onc.getActiveValue('Type') == 'VPN' && |
| onc.getActiveValue('VPN.Type') == 'ThirdPartyVPN') { |
| var providerName = |
| onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName') || |
| loadTimeData.getString('defaultThirdPartyProviderName'); |
| name = loadTimeData.getStringF('vpnNameTemplate', providerName, name); |
| } |
| $('network-details-title').textContent = name; |
| |
| var connectionStateString = onc.getTranslatedValue('ConnectionState'); |
| $('network-details-subtitle-status').textContent = connectionStateString; |
| |
| var typeKey; |
| var type = this.type_; |
| if (type == 'Ethernet') |
| typeKey = 'ethernetTitle'; |
| else if (type == 'WiFi') |
| typeKey = 'wifiTitle'; |
| else if (type == 'WiMAX') |
| typeKey = 'wimaxTitle'; |
| else if (type == 'Cellular') |
| typeKey = 'cellularTitle'; |
| else if (type == 'VPN') |
| typeKey = 'vpnTitle'; |
| else |
| typeKey = null; |
| var typeLabel = $('network-details-subtitle-type'); |
| var typeSeparator = $('network-details-subtitle-separator'); |
| if (typeKey) { |
| typeLabel.textContent = loadTimeData.getString(typeKey); |
| typeLabel.hidden = false; |
| typeSeparator.hidden = false; |
| } else { |
| typeLabel.hidden = true; |
| typeSeparator.hidden = true; |
| } |
| }, |
| |
| /** |
| * Helper method to insert a 'user' option into the Apn list. |
| * @param {Object} userOption The 'user' apn dictionary |
| * @private |
| */ |
| insertApnUserOption_: function(userOption) { |
| // Add the 'user' option before the last option ('other') |
| var apnSelector = $('select-apn'); |
| assert(apnSelector.length > 0); |
| var otherOption = apnSelector[apnSelector.length - 1]; |
| apnSelector.add(userOption, otherOption); |
| this.userApnIndex_ = apnSelector.length - 2; |
| this.selectedApnIndex_ = this.userApnIndex_; |
| }, |
| |
| /** |
| * Helper method called from initializeApnList to populate the Apn list. |
| * @param {Array} apnList List of available APNs. |
| * @private |
| */ |
| populateApnList_: function(apnList) { |
| var onc = this.onc_; |
| var apnSelector = $('select-apn'); |
| assert(apnSelector.length == 1); |
| var otherOption = apnSelector[0]; |
| var activeApn = onc.getActiveValue('Cellular.APN.AccessPointName'); |
| var lastGoodApn = |
| onc.getActiveValue('Cellular.LastGoodAPN.AccessPointName'); |
| for (var i = 0; i < apnList.length; i++) { |
| var apnDict = apnList[i]; |
| var localizedName = apnDict['LocalizedName']; |
| var name = localizedName ? localizedName : apnDict['Name']; |
| var accessPointName = apnDict['AccessPointName']; |
| var option = document.createElement('option'); |
| option.textContent = |
| name ? (name + ' (' + accessPointName + ')') : accessPointName; |
| option.value = i; |
| // Insert new option before 'other' option. |
| apnSelector.add(option, otherOption); |
| if (this.selectedApnIndex_ != -1) |
| continue; |
| // If this matches the active Apn name, or LastGoodApn name (or there |
| // is no last good APN), set it as the selected Apn. |
| if ((activeApn == accessPointName) || |
| (!activeApn && (!lastGoodApn || lastGoodApn == accessPointName))) { |
| this.selectedApnIndex_ = i; |
| } |
| } |
| if (this.selectedApnIndex_ == -1 && activeApn) { |
| this.userApn_ = activeApn; |
| // Create a 'user' entry for any active apn not in the list. |
| var userOption = document.createElement('option'); |
| userOption.textContent = activeApn; |
| userOption.value = -1; |
| this.insertApnUserOption_(userOption); |
| } |
| }, |
| |
| /** |
| * Helper method called from initializeDetailsPage to initialize the Apn |
| * list. |
| * @private |
| */ |
| initializeApnList_: function() { |
| this.selectedApnIndex_ = -1; |
| this.userApnIndex_ = -1; |
| |
| var onc = this.onc_; |
| var apnSelector = /** @type {HTMLSelectElement} */($('select-apn')); |
| |
| // Clear APN lists, keep only last element, 'other'. |
| while (apnSelector.length != 1) |
| apnSelector.remove(0); |
| |
| var apnList = onc.getActiveValue('Cellular.APNList'); |
| if (apnList) { |
| // Populate the list with the existing APNs. |
| this.populateApnList_(apnList); |
| } else { |
| // Create a single 'default' entry. |
| var otherOption = apnSelector[0]; |
| var defaultOption = /** @type {HTMLElement} */( |
| document.createElement('option')); |
| defaultOption.textContent = |
| loadTimeData.getString('cellularApnUseDefault'); |
| defaultOption.value = -1; |
| // Add 'default' entry before 'other' option |
| apnSelector.add(defaultOption, otherOption); |
| assert(apnSelector.length == 2); // 'default', 'other' |
| this.selectedApnIndex_ = 0; // Select 'default' |
| } |
| assert(this.selectedApnIndex_ >= 0); |
| apnSelector.selectedIndex = this.selectedApnIndex_; |
| updateHidden('.apn-list-view', false); |
| updateHidden('.apn-details-view', true); |
| }, |
| |
| /** |
| * Helper function for setting APN properties. |
| * @param {Object} apnValue Dictionary of APN properties. |
| * @private |
| */ |
| setActiveApn_: function(apnValue) { |
| var activeApn = {}; |
| var apnName = apnValue['AccessPointName']; |
| if (apnName) { |
| activeApn['AccessPointName'] = apnName; |
| activeApn['Username'] = stringFromValue(apnValue['Username']); |
| activeApn['Password'] = stringFromValue(apnValue['Password']); |
| } |
| // Set the cached ONC data. |
| this.onc_.setProperty('Cellular.APN', activeApn); |
| // Set an ONC object with just the APN values. |
| var oncData = new OncData({}); |
| oncData.setProperty('Cellular.APN', activeApn); |
| chrome.networkingPrivate.setProperties(this.onc_.guid(), |
| oncData.getData()); |
| }, |
| |
| /** |
| * Event Listener for the cellular-apn-use-default button. |
| * @private |
| */ |
| setDefaultApn_: function() { |
| var apnSelector = /** @type {HTMLSelectElement} */($('select-apn')); |
| |
| // Remove the 'user' entry if it exists. |
| if (this.userApnIndex_ != -1) { |
| assert(this.userApnIndex_ < apnSelector.length - 1); |
| apnSelector.remove(this.userApnIndex_); |
| this.userApnIndex_ = -1; |
| } |
| |
| var apnList = this.onc_.getActiveValue('Cellular.APNList'); |
| var iApn = (apnList != undefined && apnList.length > 0) ? 0 : -1; |
| apnSelector.selectedIndex = iApn; |
| this.selectedApnIndex_ = iApn; |
| |
| // Clear any user APN entry to inform Chrome to use the default APN. |
| this.setActiveApn_({}); |
| |
| updateHidden('.apn-list-view', false); |
| updateHidden('.apn-details-view', true); |
| }, |
| |
| /** |
| * Event Listener for the cellular-apn-set button. |
| * @private |
| */ |
| setApn_: function(apnValue) { |
| if (apnValue == '') |
| return; |
| |
| var apnSelector = /** @type {HTMLSelectElement} */($('select-apn')); |
| |
| var activeApn = {}; |
| activeApn['AccessPointName'] = stringFromValue(apnValue); |
| activeApn['Username'] = stringFromValue($('cellular-apn-username').value); |
| activeApn['Password'] = stringFromValue($('cellular-apn-password').value); |
| this.setActiveApn_(activeApn); |
| // Set the user selected APN. |
| this.userApn_ = activeApn; |
| |
| // Remove any existing 'user' entry. |
| if (this.userApnIndex_ != -1) { |
| assert(this.userApnIndex_ < apnSelector.length - 1); |
| apnSelector.remove(this.userApnIndex_); |
| this.userApnIndex_ = -1; |
| } |
| |
| // Create a new 'user' entry with the new active apn. |
| var option = document.createElement('option'); |
| option.textContent = activeApn['AccessPointName']; |
| option.value = -1; |
| option.selected = true; |
| this.insertApnUserOption_(option); |
| |
| updateHidden('.apn-list-view', false); |
| updateHidden('.apn-details-view', true); |
| }, |
| |
| /** |
| * Event Listener for the cellular-apn-cancel button. |
| * @private |
| */ |
| cancelApn_: function() { this.initializeApnList_(); }, |
| |
| /** |
| * Event Listener for the select-apn button. |
| * @private |
| */ |
| selectApn_: function() { |
| var onc = this.onc_; |
| var apnSelector = $('select-apn'); |
| if (apnSelector[apnSelector.selectedIndex].value != -1) { |
| var apnList = onc.getActiveValue('Cellular.APNList'); |
| var apnIndex = apnSelector.selectedIndex; |
| assert(apnIndex < apnList.length); |
| this.selectedApnIndex_ = apnIndex; |
| this.setActiveApn_(apnList[apnIndex]); |
| } else if (apnSelector.selectedIndex == this.userApnIndex_) { |
| this.selectedApnIndex_ = apnSelector.selectedIndex; |
| this.setActiveApn_(this.userApn_); |
| } else { // 'Other' |
| var apnDict; |
| if (this.userApn_['AccessPointName']) { |
| // Fill in the details fields with the existing 'user' config. |
| apnDict = this.userApn_; |
| } else { |
| // No 'user' config, use the current values. |
| apnDict = {}; |
| apnDict['AccessPointName'] = |
| onc.getActiveValue('Cellular.APN.AccessPointName'); |
| apnDict['Username'] = onc.getActiveValue('Cellular.APN.Username'); |
| apnDict['Password'] = onc.getActiveValue('Cellular.APN.Password'); |
| } |
| $('cellular-apn').value = stringFromValue(apnDict['AccessPointName']); |
| $('cellular-apn-username').value = stringFromValue(apnDict['Username']); |
| $('cellular-apn-password').value = stringFromValue(apnDict['Password']); |
| updateHidden('.apn-list-view', true); |
| updateHidden('.apn-details-view', false); |
| } |
| } |
| }; |
| |
| /** |
| * Enables or Disables all buttons that provide operations on the cellular |
| * network. |
| */ |
| DetailsInternetPage.changeCellularButtonsState = function(disable) { |
| var buttonsToDisableList = |
| new Array('details-internet-login', |
| 'details-internet-disconnect', |
| 'details-internet-configure', |
| 'activate-details', |
| 'view-account-details'); |
| |
| for (var i = 0; i < buttonsToDisableList.length; ++i) { |
| var button = $(buttonsToDisableList[i]); |
| button.disabled = disable; |
| } |
| }; |
| |
| /** |
| * If the network is not already activated, starts the activation process or |
| * shows the activation UI. Otherwise does nothing. |
| */ |
| DetailsInternetPage.activateCellular = function(guid) { |
| chrome.networkingPrivate.getProperties(guid, function(properties) { |
| var oncData = new OncData(properties); |
| if (oncData.getActiveValue('Cellular.ActivationState') == 'Activated') { |
| return; |
| } |
| var carrier = oncData.getActiveValue('Cellular.Carrier'); |
| if (carrier == CarrierSprint) { |
| // Sprint is directly ativated, call startActivate(). |
| chrome.networkingPrivate.startActivate(guid, ''); |
| } else { |
| chrome.send('showMorePlanInfo', [guid]); |
| } |
| }); |
| }; |
| |
| /** |
| * Performs minimal initialization of the InternetDetails dialog in |
| * preparation for showing proxy-settings. |
| */ |
| DetailsInternetPage.initializeProxySettings = function() { |
| DetailsInternetPage.getInstance().initializePageContents_(); |
| }; |
| |
| /** |
| * Displays the InternetDetails dialog with only the proxy settings visible. |
| */ |
| DetailsInternetPage.showProxySettings = function() { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| $('network-details-header').hidden = true; |
| $('activate-details').hidden = true; |
| $('view-account-details').hidden = true; |
| $('web-proxy-auto-discovery').hidden = true; |
| detailsPage.showProxy_ = true; |
| updateHidden('#internet-tab', true); |
| updateHidden('#details-tab-strip', true); |
| updateHidden('#details-internet-page .action-area', true); |
| detailsPage.updateControls(); |
| detailsPage.visible = true; |
| sendChromeMetricsAction('Options_NetworkShowProxyTab'); |
| }; |
| |
| /** |
| * Initializes even handling for keyboard driven flow. |
| */ |
| DetailsInternetPage.initializeKeyboardFlow = function() { |
| keyboard.initializeKeyboardFlow(false); |
| }; |
| |
| DetailsInternetPage.updateProxySettings = function(type) { |
| var proxyHost = null, |
| proxyPort = null; |
| |
| if (type == 'cros.session.proxy.singlehttp') { |
| proxyHost = 'proxy-host-single-name'; |
| proxyPort = 'proxy-host-single-port'; |
| } else if (type == 'cros.session.proxy.httpurl') { |
| proxyHost = 'proxy-host-name'; |
| proxyPort = 'proxy-host-port'; |
| } else if (type == 'cros.session.proxy.httpsurl') { |
| proxyHost = 'secure-proxy-host-name'; |
| proxyPort = 'secure-proxy-port'; |
| } else if (type == 'cros.session.proxy.ftpurl') { |
| proxyHost = 'ftp-proxy'; |
| proxyPort = 'ftp-proxy-port'; |
| } else if (type == 'cros.session.proxy.socks') { |
| proxyHost = 'socks-host'; |
| proxyPort = 'socks-port'; |
| } else { |
| return; |
| } |
| |
| var hostValue = $(proxyHost).value; |
| if (hostValue.indexOf(':') !== -1) { |
| if (hostValue.match(/:/g).length == 1) { |
| hostValue = hostValue.split(':'); |
| $(proxyHost).value = hostValue[0]; |
| $(proxyPort).value = hostValue[1]; |
| } |
| } |
| }; |
| |
| DetailsInternetPage.loginFromDetails = function() { |
| DetailsInternetPage.configureOrConnect(); |
| PageManager.closeOverlay(); |
| }; |
| |
| /** |
| * This function identifies unconfigured networks and networks that are |
| * likely to fail (e.g. due to a bad passphrase on a previous connect |
| * attempt). For such networks a configure dialog will be opened. Otherwise |
| * a connection will be attempted. |
| */ |
| DetailsInternetPage.configureOrConnect = function() { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| if (detailsPage.type_ == 'WiFi') |
| sendChromeMetricsAction('Options_NetworkConnectToWifi'); |
| else if (detailsPage.type_ == 'VPN') |
| sendChromeMetricsAction('Options_NetworkConnectToVPN'); |
| |
| var onc = detailsPage.onc_; |
| var guid = onc.guid(); |
| var type = onc.getActiveValue('Type'); |
| |
| // Built-in VPNs do not correctly set 'Connectable', so we always show the |
| // configuration UI. |
| if (type == 'VPN') { |
| if (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') { |
| chrome.send('configureNetwork', [guid]); |
| return; |
| } |
| } |
| |
| // If 'Connectable' is false for WiFi or WiMAX, Shill requires |
| // additional configuration to connect, so show the configuration UI. |
| if ((type == 'WiFi' || type == 'WiMAX') && |
| !onc.getActiveValue('Connectable')) { |
| chrome.send('configureNetwork', [guid]); |
| return; |
| } |
| |
| // Secure WiFi networks with ErrorState set most likely require |
| // configuration (e.g. a correct passphrase) before connecting. |
| if (type == 'WiFi' && onc.getWiFiSecurity() != 'None') { |
| var errorState = onc.getActiveValue('ErrorState'); |
| if (errorState && errorState != 'Unknown') { |
| chrome.send('configureNetwork', [guid]); |
| return; |
| } |
| } |
| |
| // Cellular networks need to be activated before they can be connected to. |
| if (type == 'Cellular') { |
| var activationState = onc.getActiveValue('Cellular.ActivationState'); |
| if (activationState != 'Activated' && activationState != 'Unknown') { |
| DetailsInternetPage.activateCellular(guid); |
| return; |
| } |
| } |
| |
| chrome.networkingPrivate.startConnect(guid); |
| }; |
| |
| DetailsInternetPage.disconnectNetwork = function() { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| if (detailsPage.type_ == 'WiFi') |
| sendChromeMetricsAction('Options_NetworkDisconnectWifi'); |
| else if (detailsPage.type_ == 'VPN') |
| sendChromeMetricsAction('Options_NetworkDisconnectVPN'); |
| chrome.networkingPrivate.startDisconnect(detailsPage.onc_.guid()); |
| PageManager.closeOverlay(); |
| }; |
| |
| DetailsInternetPage.configureNetwork = function() { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| // This is an explicit request to show the configure dialog; do not show |
| // the enrollment dialog for networks missing a certificate. |
| var forceShow = true; |
| chrome.send('configureNetwork', [detailsPage.onc_.guid(), forceShow]); |
| PageManager.closeOverlay(); |
| }; |
| |
| DetailsInternetPage.activateFromDetails = function() { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| if (detailsPage.type_ == 'Cellular') |
| DetailsInternetPage.activateCellular(detailsPage.onc_.guid()); |
| PageManager.closeOverlay(); |
| }; |
| |
| /** |
| * Event handler called when the details page is closed. Sends changed |
| * properties to Chrome and closes the overlay. |
| */ |
| DetailsInternetPage.setDetails = function() { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| var type = detailsPage.type_; |
| var oncData = new OncData({}); |
| var autoConnectCheckboxId = ''; |
| if (type == 'WiFi') { |
| var preferredCheckbox = |
| assertInstanceof($('prefer-network-wifi'), HTMLInputElement); |
| if (!preferredCheckbox.hidden && !preferredCheckbox.disabled) { |
| var kPreferredPriority = 1; |
| var priority = preferredCheckbox.checked ? kPreferredPriority : 0; |
| oncData.setProperty('Priority', priority); |
| sendChromeMetricsAction('Options_NetworkSetPrefer'); |
| } |
| autoConnectCheckboxId = 'auto-connect-network-wifi'; |
| } else if (type == 'WiMAX') { |
| autoConnectCheckboxId = 'auto-connect-network-wimax'; |
| } else if (type == 'Cellular') { |
| autoConnectCheckboxId = 'auto-connect-network-cellular'; |
| } else if (type == 'VPN') { |
| var providerType = detailsPage.onc_.getActiveValue('VPN.Type'); |
| if (providerType != 'ThirdPartyVPN') { |
| oncData.setProperty('VPN.Type', providerType); |
| oncData.setProperty('VPN.Host', $('inet-server-hostname').value); |
| autoConnectCheckboxId = 'auto-connect-network-vpn'; |
| } |
| } |
| if (autoConnectCheckboxId != '') { |
| var autoConnectCheckbox = |
| assertInstanceof($(autoConnectCheckboxId), HTMLInputElement); |
| if (!autoConnectCheckbox.hidden && !autoConnectCheckbox.disabled) { |
| var autoConnectKey = type + '.AutoConnect'; |
| oncData.setProperty(autoConnectKey, !!autoConnectCheckbox.checked); |
| sendChromeMetricsAction('Options_NetworkAutoConnect'); |
| } |
| } |
| |
| var nameServerTypes = ['automatic', 'google', 'user']; |
| var nameServerType = 'automatic'; |
| for (var i = 0; i < nameServerTypes.length; ++i) { |
| if ($(nameServerTypes[i] + '-dns-radio').checked) { |
| nameServerType = nameServerTypes[i]; |
| break; |
| } |
| } |
| var ipConfig = detailsPage.getIpConfig_(nameServerType); |
| var ipAddressType = ('IPAddress' in ipConfig) ? 'Static' : 'DHCP'; |
| var nameServersType = ('NameServers' in ipConfig) ? 'Static' : 'DHCP'; |
| oncData.setProperty('IPAddressConfigType', ipAddressType); |
| oncData.setProperty('NameServersConfigType', nameServersType); |
| oncData.setProperty('StaticIPConfig', ipConfig); |
| |
| var data = oncData.getData(); |
| if (Object.keys(data).length > 0) { |
| // TODO(stevenjb): Only set changed properties. |
| chrome.networkingPrivate.setProperties(detailsPage.onc_.guid(), data); |
| } |
| |
| PageManager.closeOverlay(); |
| }; |
| |
| /** |
| * Event handler called when the name server type changes. |
| * @param {string} type The selected name sever type, 'automatic', 'google', |
| * or 'user'. |
| */ |
| DetailsInternetPage.updateNameServerDisplay = function(type) { |
| var editable = type == 'user'; |
| var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'), |
| $('ipconfig-dns3'), $('ipconfig-dns4')]; |
| for (var i = 0; i < fields.length; ++i) { |
| fields[i].editable = editable; |
| } |
| if (editable) |
| $('ipconfig-dns1').focus(); |
| |
| var automaticDns = $('automatic-dns-display'); |
| var googleDns = $('google-dns-display'); |
| var userDns = $('user-dns-settings'); |
| switch (type) { |
| case 'automatic': |
| automaticDns.setAttribute('selected', ''); |
| googleDns.removeAttribute('selected'); |
| userDns.removeAttribute('selected'); |
| break; |
| case 'google': |
| automaticDns.removeAttribute('selected'); |
| googleDns.setAttribute('selected', ''); |
| userDns.removeAttribute('selected'); |
| break; |
| case 'user': |
| automaticDns.removeAttribute('selected'); |
| googleDns.removeAttribute('selected'); |
| userDns.setAttribute('selected', ''); |
| break; |
| } |
| }; |
| |
| /** |
| * Method called from Chrome when the ONC properties for the displayed |
| * network may have changed. |
| * @param {Object} oncData The updated ONC dictionary for the network. |
| */ |
| DetailsInternetPage.updateConnectionData = function(oncData) { |
| var detailsPage = DetailsInternetPage.getInstance(); |
| if (!detailsPage.visible) |
| return; |
| |
| if (oncData.GUID != detailsPage.onc_.guid()) |
| return; |
| |
| // Update our cached data object. |
| detailsPage.onc_ = new OncData(oncData); |
| |
| detailsPage.populateHeader_(); |
| detailsPage.updateConnectionButtonVisibility_(); |
| detailsPage.updateDetails_(); |
| }; |
| |
| /** |
| * Initializes the details page with the provided ONC data. |
| * @param {Object} oncData Dictionary of ONC properties. |
| */ |
| DetailsInternetPage.initializeDetailsPage = function(oncData) { |
| var onc = new OncData(oncData); |
| |
| var detailsPage = DetailsInternetPage.getInstance(); |
| detailsPage.onc_ = onc; |
| var type = onc.getActiveValue('Type'); |
| detailsPage.type_ = type; |
| |
| sendShowDetailsMetrics(type, onc.getActiveValue('ConnectionState')); |
| |
| detailsPage.populateHeader_(); |
| detailsPage.updateConnectionButtonVisibility_(); |
| detailsPage.updateDetails_(); |
| |
| // TODO(stevenjb): Some of the setup below should be moved to |
| // updateDetails_() so that updates are reflected in the UI. |
| |
| // Only show proxy for remembered networks. |
| var remembered = onc.getSource() != 'None'; |
| if (remembered) { |
| detailsPage.showProxy_ = true; |
| // Inform Chrome which network to use for proxy configuration. |
| chrome.send('selectNetwork', [detailsPage.onc_.guid()]); |
| } else { |
| detailsPage.showProxy_ = false; |
| } |
| |
| $('web-proxy-auto-discovery').hidden = true; |
| |
| var restricted = onc.getActiveValue('RestrictedConnectivity'); |
| var restrictedString = loadTimeData.getString( |
| restricted ? 'restrictedYes' : 'restrictedNo'); |
| |
| // These objects contain an 'automatic' property that is displayed when |
| // ip-automatic-configuration-checkbox is checked, and a 'value' property |
| // that is displayed when unchecked and used to set the associated ONC |
| // property for StaticIPConfig on commit. |
| var inetAddress = {}; |
| var inetNetmask = {}; |
| var inetGateway = {}; |
| var ipv6Address = {}; |
| |
| var inetNameServersString; |
| |
| var ipconfigList = onc.getActiveValue('IPConfigs'); |
| if (Array.isArray(ipconfigList)) { |
| for (var i = 0; i < ipconfigList.length; ++i) { |
| var ipconfig = ipconfigList[i]; |
| var ipType = ipconfig['Type']; |
| var address = ipconfig['IPAddress']; |
| if (ipType != 'IPv4') { |
| if (ipType == 'IPv6' && !ipv6Address.value) { |
| ipv6Address.automatic = address; |
| ipv6Address.value = address; |
| } |
| continue; |
| } |
| if (inetAddress.value) |
| continue; // ipv4 address already provided. |
| inetAddress.automatic = address; |
| inetAddress.value = address; |
| var netmask = prefixLengthToNetmask(ipconfig['RoutingPrefix']); |
| inetNetmask.automatic = netmask; |
| inetNetmask.value = netmask; |
| var gateway = ipconfig['Gateway']; |
| inetGateway.automatic = gateway; |
| inetGateway.value = gateway; |
| if ('WebProxyAutoDiscoveryUrl' in ipconfig) { |
| $('web-proxy-auto-discovery').hidden = false; |
| $('web-proxy-auto-discovery-url').value = |
| ipconfig['WebProxyAutoDiscoveryUrl']; |
| } |
| if ('NameServers' in ipconfig) { |
| var inetNameServers = ipconfig['NameServers']; |
| inetNameServers = inetNameServers.sort(); |
| inetNameServersString = inetNameServers.join(','); |
| } |
| } |
| } |
| |
| // Override the 'automatic' properties with the saved DHCP values if the |
| // saved value is set, and set any unset 'value' properties. |
| var savedNameServersString; |
| var savedIpAddress = onc.getActiveValue('SavedIPConfig.IPAddress'); |
| if (savedIpAddress != undefined) { |
| inetAddress.automatic = savedIpAddress; |
| if (!inetAddress.value) |
| inetAddress.value = savedIpAddress; |
| } |
| var savedPrefix = onc.getActiveValue('SavedIPConfig.RoutingPrefix'); |
| if (savedPrefix != undefined) { |
| assert(typeof savedPrefix == 'number'); |
| var savedNetmask = prefixLengthToNetmask( |
| /** @type {number} */(savedPrefix)); |
| inetNetmask.automatic = savedNetmask; |
| if (!inetNetmask.value) |
| inetNetmask.value = savedNetmask; |
| } |
| var savedGateway = onc.getActiveValue('SavedIPConfig.Gateway'); |
| if (savedGateway != undefined) { |
| inetGateway.automatic = savedGateway; |
| if (!inetGateway.value) |
| inetGateway.value = savedGateway; |
| } |
| |
| var savedNameServers = onc.getActiveValue('SavedIPConfig.NameServers'); |
| if (savedNameServers) { |
| savedNameServers = savedNameServers.sort(); |
| savedNameServersString = savedNameServers.join(','); |
| } |
| |
| var ipAutoConfig = 'automatic'; |
| if (onc.getActiveValue('IPAddressConfigType') == 'Static') { |
| ipAutoConfig = 'user'; |
| var staticIpAddress = onc.getActiveValue('StaticIPConfig.IPAddress'); |
| inetAddress.user = staticIpAddress; |
| inetAddress.value = staticIpAddress; |
| |
| var staticPrefix = onc.getActiveValue('StaticIPConfig.RoutingPrefix'); |
| if (typeof staticPrefix != 'number') |
| staticPrefix = 0; |
| var staticNetmask = prefixLengthToNetmask( |
| /** @type {number} */ (staticPrefix)); |
| inetNetmask.user = staticNetmask; |
| inetNetmask.value = staticNetmask; |
| |
| var staticGateway = onc.getActiveValue('StaticIPConfig.Gateway'); |
| inetGateway.user = staticGateway; |
| inetGateway.value = staticGateway; |
| } |
| |
| var staticNameServersString; |
| if (onc.getActiveValue('NameServersConfigType') == 'Static') { |
| var staticNameServers = onc.getActiveValue('StaticIPConfig.NameServers'); |
| staticNameServers = staticNameServers.sort(); |
| staticNameServersString = staticNameServers.join(','); |
| } |
| |
| $('ip-automatic-configuration-checkbox').checked = |
| ipAutoConfig == 'automatic'; |
| |
| inetAddress.autoConfig = ipAutoConfig; |
| inetNetmask.autoConfig = ipAutoConfig; |
| inetGateway.autoConfig = ipAutoConfig; |
| |
| var configureAddressField = function(field, model) { |
| IPAddressField.decorate(field); |
| field.model = model; |
| field.editable = model.autoConfig == 'user'; |
| }; |
| configureAddressField($('ip-address'), inetAddress); |
| configureAddressField($('ipv6-address'), ipv6Address); |
| configureAddressField($('ip-netmask'), inetNetmask); |
| configureAddressField($('ip-gateway'), inetGateway); |
| |
| // Set Nameserver fields. Nameservers are 'automatic' by default. If a |
| // static namerserver is set, use that unless it does not match a non |
| // empty 'NameServers' value (indicating that the custom nameservers are |
| // invalid or not being applied for some reason). TODO(stevenjb): Only |
| // set these properites if they change so that invalid custom values do |
| // not get lost. |
| var nameServerType = 'automatic'; |
| if (staticNameServersString && |
| (!inetNameServersString || |
| staticNameServersString == inetNameServersString)) { |
| if (staticNameServersString == GoogleNameServers.join(',')) |
| nameServerType = 'google'; |
| else |
| nameServerType = 'user'; |
| } |
| if (nameServerType == 'automatic') |
| $('automatic-dns-display').textContent = inetNameServersString; |
| else |
| $('automatic-dns-display').textContent = savedNameServersString; |
| $('google-dns-display').textContent = GoogleNameServers.join(','); |
| |
| var nameServersUser = []; |
| if (staticNameServers) { |
| nameServersUser = staticNameServers; |
| } else if (savedNameServers) { |
| // Pre-populate with values provided by DHCP server. |
| nameServersUser = savedNameServers; |
| } |
| |
| var nameServerModels = []; |
| for (var i = 0; i < 4; ++i) |
| nameServerModels.push({value: nameServersUser[i] || ''}); |
| |
| $(nameServerType + '-dns-radio').checked = true; |
| configureAddressField($('ipconfig-dns1'), nameServerModels[0]); |
| configureAddressField($('ipconfig-dns2'), nameServerModels[1]); |
| configureAddressField($('ipconfig-dns3'), nameServerModels[2]); |
| configureAddressField($('ipconfig-dns4'), nameServerModels[3]); |
| |
| DetailsInternetPage.updateNameServerDisplay(nameServerType); |
| |
| var macAddress = onc.getActiveValue('MacAddress'); |
| if (macAddress) { |
| $('hardware-address').textContent = macAddress; |
| $('hardware-address-row').style.display = 'table-row'; |
| } else { |
| // This is most likely a device without a hardware address. |
| $('hardware-address-row').style.display = 'none'; |
| } |
| |
| var setOrHideParent = function(field, property) { |
| if (property != undefined) { |
| $(field).textContent = property; |
| $(field).parentElement.hidden = false; |
| } else { |
| $(field).parentElement.hidden = true; |
| } |
| }; |
| |
| var networkName = onc.getTranslatedValue('Name'); |
| |
| // Signal strength as percentage (for WiFi and WiMAX). |
| var signalStrength; |
| if (type == 'WiFi' || type == 'WiMAX') |
| signalStrength = onc.getActiveValue(type + '.SignalStrength'); |
| if (!signalStrength) |
| signalStrength = 0; |
| var strengthFormat = loadTimeData.getString('inetSignalStrengthFormat'); |
| var strengthString = strengthFormat.replace('$1', signalStrength); |
| |
| if (type == 'WiFi') { |
| OptionsPage.showTab($('wifi-network-nav-tab')); |
| $('wifi-restricted-connectivity').textContent = restrictedString; |
| var ssid = onc.getActiveValue('WiFi.SSID'); |
| $('wifi-ssid').textContent = ssid ? ssid : networkName; |
| setOrHideParent('wifi-bssid', onc.getActiveValue('WiFi.BSSID')); |
| var security = onc.getWiFiSecurity(); |
| if (security == 'None') |
| security = undefined; |
| setOrHideParent('wifi-security', security); |
| // Frequency is in MHz. |
| var frequency = onc.getActiveValue('WiFi.Frequency'); |
| if (!frequency) |
| frequency = 0; |
| var frequencyFormat = loadTimeData.getString('inetFrequencyFormat'); |
| frequencyFormat = frequencyFormat.replace('$1', frequency); |
| $('wifi-frequency').textContent = frequencyFormat; |
| $('wifi-signal-strength').textContent = strengthString; |
| setOrHideParent('wifi-hardware-address', |
| onc.getActiveValue('MacAddress')); |
| var priority = onc.getActiveValue('Priority'); |
| $('prefer-network-wifi').checked = priority > 0; |
| $('prefer-network-wifi').disabled = !remembered; |
| $('auto-connect-network-wifi').checked = |
| onc.getActiveValue('WiFi.AutoConnect'); |
| $('auto-connect-network-wifi').disabled = !remembered; |
| } else if (type == 'WiMAX') { |
| OptionsPage.showTab($('wimax-network-nav-tab')); |
| $('wimax-restricted-connectivity').textContent = restrictedString; |
| |
| $('auto-connect-network-wimax').checked = |
| onc.getActiveValue('WiMAX.AutoConnect'); |
| $('auto-connect-network-wimax').disabled = !remembered; |
| var identity = onc.getActiveValue('WiMAX.EAP.Identity'); |
| setOrHideParent('wimax-eap-identity', identity); |
| $('wimax-signal-strength').textContent = strengthString; |
| } else if (type == 'Cellular') { |
| OptionsPage.showTab($('cellular-conn-nav-tab')); |
| |
| var isGsm = onc.getActiveValue('Cellular.Family') == 'GSM'; |
| |
| $('service-name').textContent = networkName; |
| |
| // TODO(stevenjb): Ideally many of these should be localized. |
| $('network-technology').textContent = |
| onc.getActiveValue('Cellular.NetworkTechnology'); |
| $('roaming-state').textContent = |
| onc.getTranslatedValue('Cellular.RoamingState'); |
| $('cellular-restricted-connectivity').textContent = restrictedString; |
| $('error-state').textContent = onc.getActiveValue('ErrorState'); |
| $('manufacturer').textContent = |
| onc.getActiveValue('Cellular.Manufacturer'); |
| $('model-id').textContent = onc.getActiveValue('Cellular.ModelID'); |
| $('firmware-revision').textContent = |
| onc.getActiveValue('Cellular.FirmwareRevision'); |
| $('hardware-revision').textContent = |
| onc.getActiveValue('Cellular.HardwareRevision'); |
| $('mdn').textContent = onc.getActiveValue('Cellular.MDN'); |
| |
| // Show ServingOperator properties only if available. |
| var servingOperatorName = |
| onc.getActiveValue('Cellular.ServingOperator.Name'); |
| var servingOperatorCode = |
| onc.getActiveValue('Cellular.ServingOperator.Code'); |
| if (servingOperatorName != undefined && |
| servingOperatorCode != undefined) { |
| $('operator-name').textContent = servingOperatorName; |
| $('operator-code').textContent = servingOperatorCode; |
| } else { |
| $('operator-name').parentElement.hidden = true; |
| $('operator-code').parentElement.hidden = true; |
| } |
| // Make sure that GSM/CDMA specific properties that shouldn't be hidden |
| // are visible. |
| updateHidden('#details-internet-page .gsm-only', false); |
| updateHidden('#details-internet-page .cdma-only', false); |
| |
| // Show IMEI/ESN/MEID/MIN/PRL only if they are available. |
| setOrHideParent('esn', onc.getActiveValue('Cellular.ESN')); |
| setOrHideParent('imei', onc.getActiveValue('Cellular.IMEI')); |
| setOrHideParent('meid', onc.getActiveValue('Cellular.MEID')); |
| setOrHideParent('min', onc.getActiveValue('Cellular.MIN')); |
| setOrHideParent('prl-version', onc.getActiveValue('Cellular.PRLVersion')); |
| |
| if (isGsm) { |
| $('iccid').textContent = onc.getActiveValue('Cellular.ICCID'); |
| $('imsi').textContent = onc.getActiveValue('Cellular.IMSI'); |
| detailsPage.initializeApnList_(); |
| } |
| $('auto-connect-network-cellular').checked = |
| onc.getActiveValue('Cellular.AutoConnect'); |
| $('auto-connect-network-cellular').disabled = false; |
| } else if (type == 'VPN') { |
| OptionsPage.showTab($('vpn-nav-tab')); |
| var providerType = onc.getActiveValue('VPN.Type'); |
| var isThirdPartyVPN = providerType == 'ThirdPartyVPN'; |
| $('vpn-tab').classList.toggle('third-party-vpn-provider', |
| isThirdPartyVPN); |
| |
| $('inet-service-name').textContent = networkName; |
| $('inet-provider-type').textContent = |
| onc.getTranslatedValue('VPN.Type'); |
| |
| if (isThirdPartyVPN) { |
| $('inet-provider-name').textContent = |
| onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName'); |
| } else { |
| var usernameKey; |
| if (providerType == 'OpenVPN') |
| usernameKey = 'VPN.OpenVPN.Username'; |
| else if (providerType == 'L2TP-IPsec') |
| usernameKey = 'VPN.L2TP.Username'; |
| |
| if (usernameKey) { |
| $('inet-username').parentElement.hidden = false; |
| $('inet-username').textContent = onc.getActiveValue(usernameKey); |
| } else { |
| $('inet-username').parentElement.hidden = true; |
| } |
| var inetServerHostname = $('inet-server-hostname'); |
| inetServerHostname.value = onc.getActiveValue('VPN.Host'); |
| inetServerHostname.resetHandler = function() { |
| PageManager.hideBubble(); |
| var recommended = onc.getRecommendedValue('VPN.Host'); |
| if (recommended != undefined) |
| inetServerHostname.value = recommended; |
| }; |
| $('auto-connect-network-vpn').checked = |
| onc.getActiveValue('VPN.AutoConnect'); |
| $('auto-connect-network-vpn').disabled = false; |
| } |
| } else { |
| OptionsPage.showTab($('internet-nav-tab')); |
| } |
| |
| // Update controlled option indicators. |
| var indicators = cr.doc.querySelectorAll( |
| '#details-internet-page .controlled-setting-indicator'); |
| for (var i = 0; i < indicators.length; i++) { |
| var managed = indicators[i].hasAttribute('managed'); |
| // TODO(stevenjb): Eliminate support for 'data' once 39 is stable. |
| var attributeName = managed ? 'managed' : 'data'; |
| var propName = indicators[i].getAttribute(attributeName); |
| if (!propName) |
| continue; |
| var propValue = managed ? |
| onc.getManagedProperty(propName) : |
| onc.getActiveValue(propName); |
| // If the property is unset or unmanaged (i.e. not an Object) skip it. |
| if (propValue == undefined || (typeof propValue != 'object')) |
| continue; |
| var event; |
| if (managed) |
| event = detailsPage.createManagedEvent_(propName, propValue); |
| else |
| event = detailsPage.createControlledEvent_(propName, |
| /** @type {{value: *, controlledBy: *, recommendedValue: *}} */( |
| propValue)); |
| indicators[i].handlePrefChange(event); |
| var forElement = $(indicators[i].getAttribute('internet-detail-for')); |
| if (forElement) { |
| if (event.value.controlledBy == 'policy') |
| forElement.disabled = true; |
| if (forElement.resetHandler) |
| indicators[i].resetHandler = forElement.resetHandler; |
| } |
| } |
| |
| detailsPage.updateControls(); |
| |
| // Don't show page name in address bar and in history to prevent people |
| // navigate here by hand and solve issue with page session restore. |
| PageManager.showPageByName('detailsInternetPage', false); |
| }; |
| |
| return { |
| DetailsInternetPage: DetailsInternetPage |
| }; |
| }); |