1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // require: onc_data.js 6 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 an API object that simulates the 11 // networkingPrivate API. See network_config.js. 12 // See crbug.com/279351 for more info. 13 14 /** @typedef {{address: (string|undefined), 15 * gateway: (string|undefined), 16 * nameServers: (string|undefined), 17 * netmask: (string|undefined), 18 * prefixLength: (number|undefined)}} 19 * @see chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc 20 */ 21 var IPInfo; 22 23 /** 24 * InternetDetailedInfo argument passed to showDetailedInfo. 25 * @see chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc 26 * @typedef {{ 27 * servicePath: string, 28 * showCarrierSelect: (boolean|undefined), 29 * showViewAccountButton: (boolean|undefined) 30 * }} 31 */ 32 var InternetDetailedInfo; 33 34 cr.define('options.internet', function() { 35 var OncData = cr.onc.OncData; 36 var Page = cr.ui.pageManager.Page; 37 var PageManager = cr.ui.pageManager.PageManager; 38 /** @const */ var IPAddressField = options.internet.IPAddressField; 39 40 /** @const */ var GoogleNameServersString = '8.8.4.4,8.8.8.8'; 41 /** @const */ var CarrierGenericUMTS = 'Generic UMTS'; 42 43 /** 44 * Helper function to set hidden attribute for elements matching a selector. 45 * @param {string} selector CSS selector for extracting a list of elements. 46 * @param {boolean} hidden New hidden value. 47 */ 48 function updateHidden(selector, hidden) { 49 var elements = cr.doc.querySelectorAll(selector); 50 for (var i = 0, el; el = elements[i]; i++) { 51 el.hidden = hidden; 52 } 53 } 54 55 /** 56 * Helper function to update the properties of the data object from the 57 * properties in the update object. 58 * @param {Object} data Object to update. 59 * @param {Object} update Object containing the updated properties. 60 */ 61 function updateDataObject(data, update) { 62 for (var prop in update) { 63 if (prop in data) 64 data[prop] = update[prop]; 65 } 66 } 67 68 /** 69 * Monitor pref change of given element. 70 * @param {Element} el Target element. 71 */ 72 function observePrefsUI(el) { 73 Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate); 74 } 75 76 /** 77 * UI pref change handler. 78 * @param {Event} e The update event. 79 */ 80 function handlePrefUpdate(e) { 81 DetailsInternetPage.getInstance().updateControls(); 82 } 83 84 /** 85 * Simple helper method for converting a field to a string. It is used to 86 * easily assign an empty string from fields that may be unknown or undefined. 87 * @param {Object} value that should be converted to a string. 88 * @return {string} the result. 89 */ 90 function stringFromValue(value) { 91 return value ? String(value) : ''; 92 } 93 94 /** 95 * @param {string} action An action to send to coreOptionsUserMetricsAction. 96 */ 97 function sendChromeMetricsAction(action) { 98 chrome.send('coreOptionsUserMetricsAction', [action]); 99 } 100 101 /** 102 * Sends the 'checked' state of a control to chrome for a network. 103 * @param {string} path The service path of the network. 104 * @param {string} message The message to send to chrome. 105 * @param {string} checkboxId The id of the checkbox with the value to send. 106 * @param {string=} opt_action Optional action to record. 107 */ 108 function sendCheckedIfEnabled(path, message, checkboxId, opt_action) { 109 var checkbox = assertInstanceof($(checkboxId), HTMLInputElement); 110 if (!checkbox.hidden && !checkbox.disabled) { 111 chrome.send(message, [path, checkbox.checked ? 'true' : 'false']); 112 if (opt_action) 113 sendChromeMetricsAction(opt_action); 114 } 115 } 116 117 /** 118 * Send metrics to Chrome when the detailed page is opened. 119 * @param {string} type The ONC type of the network being shown. 120 * @param {string} state The ONC network state. 121 */ 122 function sendShowDetailsMetrics(type, state) { 123 if (type == 'WiFi') { 124 sendChromeMetricsAction('Options_NetworkShowDetailsWifi'); 125 if (state != 'NotConnected') 126 sendChromeMetricsAction('Options_NetworkShowDetailsWifiConnected'); 127 } else if (type == 'Cellular') { 128 sendChromeMetricsAction('Options_NetworkShowDetailsCellular'); 129 if (state != 'NotConnected') 130 sendChromeMetricsAction('Options_NetworkShowDetailsCellularConnected'); 131 } else if (type == 'VPN') { 132 sendChromeMetricsAction('Options_NetworkShowDetailsVPN'); 133 if (state != 'NotConnected') 134 sendChromeMetricsAction('Options_NetworkShowDetailsVPNConnected'); 135 } 136 } 137 138 /** 139 * Returns the netmask as a string for a given prefix length. 140 * @param {number} prefixLength The ONC routing prefix length. 141 * @return {string} The corresponding netmask. 142 */ 143 function prefixLengthToNetmask(prefixLength) { 144 // Return the empty string for invalid inputs. 145 if (prefixLength < 0 || prefixLength > 32) 146 return ''; 147 var netmask = ''; 148 for (var i = 0; i < 4; ++i) { 149 var remainder = 8; 150 if (prefixLength >= 8) { 151 prefixLength -= 8; 152 } else { 153 remainder = prefixLength; 154 prefixLength = 0; 155 } 156 if (i > 0) 157 netmask += '.'; 158 var value = 0; 159 if (remainder != 0) 160 value = ((2 << (remainder - 1)) - 1) << (8 - remainder); 161 netmask += value.toString(); 162 } 163 return netmask; 164 } 165 166 ///////////////////////////////////////////////////////////////////////////// 167 // DetailsInternetPage class: 168 169 /** 170 * Encapsulated handling of ChromeOS internet details overlay page. 171 * @constructor 172 * @extends {cr.ui.pageManager.Page} 173 */ 174 function DetailsInternetPage() { 175 // Cached Apn properties 176 this.userApnIndex_ = -1; 177 this.selectedApnIndex_ = -1; 178 this.userApn_ = {}; 179 // We show the Proxy configuration tab for remembered networks and when 180 // configuring a proxy from the login screen. 181 this.showProxy_ = false; 182 // In Chrome we sometimes want to enable the Cellular carrier select UI. 183 this.showCarrierSelect_ = false; 184 // In Chrome we sometimes want to show the 'View Account' button. 185 this.showViewAccountButton_ = false; 186 187 Page.call(this, 'detailsInternetPage', '', 'details-internet-page'); 188 } 189 190 cr.addSingletonGetter(DetailsInternetPage); 191 192 DetailsInternetPage.prototype = { 193 __proto__: Page.prototype, 194 195 /** @override */ 196 initializePage: function() { 197 Page.prototype.initializePage.call(this); 198 this.initializePageContents_(); 199 this.showNetworkDetails_(); 200 }, 201 202 /** 203 * Auto-activates the network details dialog if network information 204 * is included in the URL. 205 */ 206 showNetworkDetails_: function() { 207 var servicePath = parseQueryParams(window.location).servicePath; 208 if (!servicePath || !servicePath.length) 209 return; 210 var networkType = ''; // ignored for 'showDetails' 211 chrome.send('networkCommand', [networkType, servicePath, 'showDetails']); 212 }, 213 214 /** 215 * Initializes the contents of the page. 216 */ 217 initializePageContents_: function() { 218 $('details-internet-dismiss').addEventListener('click', function(event) { 219 DetailsInternetPage.setDetails(); 220 }); 221 222 $('details-internet-login').addEventListener('click', function(event) { 223 DetailsInternetPage.setDetails(); 224 DetailsInternetPage.loginFromDetails(); 225 }); 226 227 $('details-internet-disconnect').addEventListener('click', 228 function(event) { 229 DetailsInternetPage.setDetails(); 230 DetailsInternetPage.disconnectNetwork(); 231 }); 232 233 $('details-internet-configure').addEventListener('click', 234 function(event) { 235 DetailsInternetPage.setDetails(); 236 DetailsInternetPage.configureNetwork(); 237 }); 238 239 $('activate-details').addEventListener('click', function(event) { 240 DetailsInternetPage.activateFromDetails(); 241 }); 242 243 $('view-account-details').addEventListener('click', function(event) { 244 chrome.send('showMorePlanInfo', 245 [DetailsInternetPage.getInstance().servicePath_]); 246 PageManager.closeOverlay(); 247 }); 248 249 $('cellular-apn-use-default').addEventListener('click', function(event) { 250 DetailsInternetPage.getInstance().setDefaultApn_(); 251 }); 252 253 $('cellular-apn-set').addEventListener('click', function(event) { 254 DetailsInternetPage.getInstance().setApn_($('cellular-apn').value); 255 }); 256 257 $('cellular-apn-cancel').addEventListener('click', function(event) { 258 DetailsInternetPage.getInstance().cancelApn_(); 259 }); 260 261 $('select-apn').addEventListener('change', function(event) { 262 DetailsInternetPage.getInstance().selectApn_(); 263 }); 264 265 $('sim-card-lock-enabled').addEventListener('click', function(event) { 266 var newValue = $('sim-card-lock-enabled').checked; 267 // Leave value as is because user needs to enter PIN code first. 268 // When PIN will be entered and value changed, 269 // we'll update UI to reflect that change. 270 $('sim-card-lock-enabled').checked = !newValue; 271 var operation = newValue ? 'setLocked' : 'setUnlocked'; 272 chrome.send('simOperation', [operation]); 273 }); 274 $('change-pin').addEventListener('click', function(event) { 275 chrome.send('simOperation', ['changePin']); 276 }); 277 278 // Proxy 279 ['proxy-host-single-port', 280 'secure-proxy-port', 281 'socks-port', 282 'ftp-proxy-port', 283 'proxy-host-port' 284 ].forEach(function(id) { 285 options.PrefPortNumber.decorate($(id)); 286 }); 287 288 options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list')); 289 $('remove-host').addEventListener('click', 290 this.handleRemoveProxyExceptions_); 291 $('add-host').addEventListener('click', this.handleAddProxyException_); 292 $('direct-proxy').addEventListener('click', this.disableManualProxy_); 293 $('manual-proxy').addEventListener('click', this.enableManualProxy_); 294 $('auto-proxy').addEventListener('click', this.disableManualProxy_); 295 $('proxy-all-protocols').addEventListener('click', 296 this.toggleSingleProxy_); 297 $('proxy-use-pac-url').addEventListener('change', 298 this.handleAutoConfigProxy_); 299 300 observePrefsUI($('direct-proxy')); 301 observePrefsUI($('manual-proxy')); 302 observePrefsUI($('auto-proxy')); 303 observePrefsUI($('proxy-all-protocols')); 304 observePrefsUI($('proxy-use-pac-url')); 305 306 $('ip-automatic-configuration-checkbox').addEventListener('click', 307 this.handleIpAutoConfig_); 308 $('automatic-dns-radio').addEventListener('click', 309 this.handleNameServerTypeChange_); 310 $('google-dns-radio').addEventListener('click', 311 this.handleNameServerTypeChange_); 312 $('user-dns-radio').addEventListener('click', 313 this.handleNameServerTypeChange_); 314 315 // We only load this string if we have the string data available 316 // because the proxy settings page on the login screen re-uses the 317 // proxy sub-page from the internet options, and it doesn't ever 318 // show the DNS settings, so we don't need this string there. 319 // The string isn't available because 320 // chrome://settings-frame/strings.js (where the string is 321 // stored) is not accessible from the login screen. 322 // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login 323 // page is fixed. http://crbug.com/242865 324 if (loadTimeData.data_) { 325 $('google-dns-label').innerHTML = 326 loadTimeData.getString('googleNameServers'); 327 } 328 }, 329 330 /** 331 * Handler for "add" event fired from userNameEdit. 332 * @param {Event} e Add event fired from userNameEdit. 333 * @private 334 */ 335 handleAddProxyException_: function(e) { 336 var exception = $('new-host').value; 337 $('new-host').value = ''; 338 339 exception = exception.trim(); 340 if (exception) 341 $('ignored-host-list').addException(exception); 342 }, 343 344 /** 345 * Handler for when the remove button is clicked 346 * @param {Event} e The click event. 347 * @private 348 */ 349 handleRemoveProxyExceptions_: function(e) { 350 var selectedItems = $('ignored-host-list').selectedItems; 351 for (var x = 0; x < selectedItems.length; x++) { 352 $('ignored-host-list').removeException(selectedItems[x]); 353 } 354 }, 355 356 /** 357 * Handler for when the IP automatic configuration checkbox is clicked. 358 * @param {Event} e The click event. 359 * @private 360 */ 361 handleIpAutoConfig_: function(e) { 362 var checked = $('ip-automatic-configuration-checkbox').checked; 363 var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')]; 364 for (var i = 0; i < fields.length; ++i) { 365 fields[i].editable = !checked; 366 if (checked) { 367 var model = fields[i].model; 368 model.value = model.automatic; 369 fields[i].model = model; 370 } 371 } 372 if (!checked) 373 $('ip-address').focus(); 374 }, 375 376 /** 377 * Handler for when the name server selection changes. 378 * @param {Event} event The click event. 379 * @private 380 */ 381 handleNameServerTypeChange_: function(event) { 382 var type = event.target.value; 383 DetailsInternetPage.updateNameServerDisplay(type); 384 }, 385 386 /** 387 * Sends the IP Config info to chrome. 388 * @param {string} nameServerType The selected name server type: 389 * 'automatic', 'google', or 'user'. 390 * @private 391 */ 392 sendIpConfig_: function(nameServerType) { 393 var userNameServerString = ''; 394 if (nameServerType == 'user') { 395 var userNameServers = []; 396 for (var i = 1; i <= 4; ++i) { 397 var nameServerField = $('ipconfig-dns' + i); 398 // Skip empty values. 399 if (nameServerField && nameServerField.model && 400 nameServerField.model.value) { 401 userNameServers.push(nameServerField.model.value); 402 } 403 } 404 userNameServerString = userNameServers.sort().join(','); 405 } 406 chrome.send('setIPConfig', 407 [this.servicePath_, 408 Boolean($('ip-automatic-configuration-checkbox').checked), 409 $('ip-address').model.value || '', 410 $('ip-netmask').model.value || '', 411 $('ip-gateway').model.value || '', 412 nameServerType, 413 userNameServerString]); 414 }, 415 416 /** 417 * Creates an indicator event for controlled properties using 418 * the same dictionary format as CoreOptionsHandler::CreateValueForPref. 419 * @param {string} name The name for the Event. 420 * @param {{value: *, controlledBy: *, recommendedValue: *}} propData 421 * Property dictionary. 422 * @private 423 */ 424 createControlledEvent_: function(name, propData) { 425 assert('value' in propData && 'controlledBy' in propData && 426 'recommendedValue' in propData); 427 var event = new Event(name); 428 event.value = { 429 value: propData.value, 430 controlledBy: propData.controlledBy, 431 recommendedValue: propData.recommendedValue 432 }; 433 return event; 434 }, 435 436 /** 437 * Creates an indicator event for controlled properties using 438 * the ONC getManagedProperties dictionary format. 439 * @param {string} name The name for the Event. 440 * @param {Object} propData ONC managed network property dictionary. 441 * @private 442 */ 443 createManagedEvent_: function(name, propData) { 444 var event = new Event(name); 445 event.value = {}; 446 447 // Set the current value and recommended value. 448 var activeValue = propData['Active']; 449 var effective = propData['Effective']; 450 if (activeValue == undefined) 451 activeValue = propData[effective]; 452 event.value.value = activeValue; 453 454 // If a property is editable then it is not enforced, and 'controlledBy' 455 // is set to 'recommended' unless effective == {User|Shared}Setting, in 456 // which case the value was modified from the recommended value. 457 // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then 458 // the set value is mandated by the policy. 459 if (propData['UserEditable']) { 460 if (effective == 'UserPolicy') 461 event.value.controlledBy = 'recommended'; 462 event.value.recommendedValue = propData['UserPolicy']; 463 } else if (propData['DeviceEditable']) { 464 if (effective == 'DevicePolicy') 465 event.value.controlledBy = 'recommended'; 466 event.value.recommendedValue = propData['DevicePolicy']; 467 } else if (effective == 'UserPolicy' || effective == 'DevicePolicy') { 468 event.value.controlledBy = 'policy'; 469 } 470 471 return event; 472 }, 473 474 /** 475 * Update details page controls. 476 */ 477 updateControls: function() { 478 // Note: onc may be undefined when called from a pref update before 479 // initialized in sendNetworkDetails. 480 var onc = this.onc_; 481 482 // Always show the ipconfig section. TODO(stevenjb): Improve the display 483 // for unconnected networks. Currently the IP address fields may be 484 // blank if the network is not connected. 485 $('ipconfig-section').hidden = false; 486 $('ipconfig-dns-section').hidden = false; 487 488 // Network type related. 489 updateHidden('#details-internet-page .cellular-details', 490 this.type_ != 'Cellular'); 491 updateHidden('#details-internet-page .wifi-details', 492 this.type_ != 'WiFi'); 493 updateHidden('#details-internet-page .wimax-details', 494 this.type_ != 'WiMAX'); 495 updateHidden('#details-internet-page .vpn-details', this.type_ != 'VPN'); 496 updateHidden('#details-internet-page .proxy-details', !this.showProxy_); 497 498 // Cellular 499 if (onc && this.type_ == 'Cellular') { 500 // Hide gsm/cdma specific elements. 501 if (onc.getActiveValue('Cellular.Family') == 'GSM') 502 updateHidden('#details-internet-page .cdma-only', true); 503 else 504 updateHidden('#details-internet-page .gsm-only', true); 505 } 506 507 // Wifi 508 509 // Hide network tab for VPN. 510 updateHidden('#details-internet-page .network-details', 511 this.type_ == 'VPN'); 512 513 // Password and shared. 514 var source = onc ? onc.getSource() : 'None'; 515 var shared = (source == 'Device' || source == 'DevicePolicy'); 516 var security = onc ? onc.getWiFiSecurity() : 'None'; 517 updateHidden('#details-internet-page #password-details', 518 this.type_ != 'WiFi' || security == 'None'); 519 updateHidden('#details-internet-page #wifi-shared-network', !shared); 520 updateHidden('#details-internet-page #prefer-network', source == 'None'); 521 522 // WiMAX. 523 updateHidden('#details-internet-page #wimax-shared-network', !shared); 524 525 // Proxy 526 this.updateProxyBannerVisibility_(); 527 this.toggleSingleProxy_(); 528 if ($('manual-proxy').checked) 529 this.enableManualProxy_(); 530 else 531 this.disableManualProxy_(); 532 }, 533 534 /** 535 * Updates info banner visibility state. This function shows the banner 536 * if proxy is managed or shared-proxies is off for shared network. 537 * @private 538 */ 539 updateProxyBannerVisibility_: function() { 540 var bannerDiv = $('network-proxy-info-banner'); 541 if (!loadTimeData.data_) { 542 // TODO(pneubeck): This temporarily prevents an exception below until 543 // i18n of the proxy dialog on the login page is 544 // fixed. http://crbug.com/242865 545 bannerDiv.hidden = true; 546 return; 547 } 548 549 // Show banner and determine its message if necessary. 550 var controlledBy = $('direct-proxy').controlledBy; 551 if (!controlledBy || controlledBy == '') { 552 bannerDiv.hidden = true; 553 } else { 554 bannerDiv.hidden = false; 555 // The possible banner texts are loaded in proxy_handler.cc. 556 var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() + 557 controlledBy.slice(1); 558 $('banner-text').textContent = loadTimeData.getString(bannerText); 559 } 560 }, 561 562 /** 563 * Handler for when the user clicks on the checkbox to allow a 564 * single proxy usage. 565 * @private 566 */ 567 toggleSingleProxy_: function() { 568 if ($('proxy-all-protocols').checked) { 569 $('multi-proxy').hidden = true; 570 $('single-proxy').hidden = false; 571 } else { 572 $('multi-proxy').hidden = false; 573 $('single-proxy').hidden = true; 574 } 575 }, 576 577 /** 578 * Handler for when the user clicks on the checkbox to enter 579 * auto configuration URL. 580 * @private 581 */ 582 handleAutoConfigProxy_: function() { 583 $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked; 584 }, 585 586 /** 587 * Handler for selecting a radio button that will disable the manual 588 * controls. 589 * @private 590 */ 591 disableManualProxy_: function() { 592 $('ignored-host-list').disabled = true; 593 $('new-host').disabled = true; 594 $('remove-host').disabled = true; 595 $('add-host').disabled = true; 596 $('proxy-all-protocols').disabled = true; 597 $('proxy-host-name').disabled = true; 598 $('proxy-host-port').disabled = true; 599 $('proxy-host-single-name').disabled = true; 600 $('proxy-host-single-port').disabled = true; 601 $('secure-proxy-host-name').disabled = true; 602 $('secure-proxy-port').disabled = true; 603 $('ftp-proxy').disabled = true; 604 $('ftp-proxy-port').disabled = true; 605 $('socks-host').disabled = true; 606 $('socks-port').disabled = true; 607 $('proxy-use-pac-url').disabled = $('auto-proxy').disabled || 608 !$('auto-proxy').checked; 609 $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled || 610 !$('proxy-use-pac-url').checked; 611 $('auto-proxy-parms').hidden = !$('auto-proxy').checked; 612 $('manual-proxy-parms').hidden = !$('manual-proxy').checked; 613 sendChromeMetricsAction('Options_NetworkManualProxy_Disable'); 614 }, 615 616 /** 617 * Handler for selecting a radio button that will enable the manual 618 * controls. 619 * @private 620 */ 621 enableManualProxy_: function() { 622 $('ignored-host-list').redraw(); 623 var allDisabled = $('manual-proxy').disabled; 624 $('ignored-host-list').disabled = allDisabled; 625 $('new-host').disabled = allDisabled; 626 $('remove-host').disabled = allDisabled; 627 $('add-host').disabled = allDisabled; 628 $('proxy-all-protocols').disabled = allDisabled; 629 $('proxy-host-name').disabled = allDisabled; 630 $('proxy-host-port').disabled = allDisabled; 631 $('proxy-host-single-name').disabled = allDisabled; 632 $('proxy-host-single-port').disabled = allDisabled; 633 $('secure-proxy-host-name').disabled = allDisabled; 634 $('secure-proxy-port').disabled = allDisabled; 635 $('ftp-proxy').disabled = allDisabled; 636 $('ftp-proxy-port').disabled = allDisabled; 637 $('socks-host').disabled = allDisabled; 638 $('socks-port').disabled = allDisabled; 639 $('proxy-use-pac-url').disabled = true; 640 $('proxy-pac-url').disabled = true; 641 $('auto-proxy-parms').hidden = !$('auto-proxy').checked; 642 $('manual-proxy-parms').hidden = !$('manual-proxy').checked; 643 sendChromeMetricsAction('Options_NetworkManualProxy_Enable'); 644 }, 645 646 /** 647 * Helper method called from showDetailedInfo and updateConnectionData. 648 * Updates visibility/enabled of the login/disconnect/configure buttons. 649 * @private 650 */ 651 updateConnectionButtonVisibilty_: function() { 652 var onc = this.onc_; 653 if (this.type_ == 'Ethernet') { 654 // Ethernet can never be connected or disconnected and can always be 655 // configured (e.g. to set security). 656 $('details-internet-login').hidden = true; 657 $('details-internet-disconnect').hidden = true; 658 $('details-internet-configure').hidden = false; 659 return; 660 } 661 662 var connectState = onc.getActiveValue('ConnectionState'); 663 if (connectState == 'NotConnected') { 664 $('details-internet-login').hidden = false; 665 // Connecting to an unconfigured network might trigger certificate 666 // installation UI. Until that gets handled here, always enable the 667 // Connect button. 668 $('details-internet-login').disabled = false; 669 $('details-internet-disconnect').hidden = true; 670 } else { 671 $('details-internet-login').hidden = true; 672 $('details-internet-disconnect').hidden = false; 673 } 674 675 var connectable = onc.getActiveValue('Connectable'); 676 if (connectState != 'Connected' && 677 (!connectable || onc.getWiFiSecurity() != 'None' || 678 (this.type_ == 'WiMAX' || this.type_ == 'VPN'))) { 679 $('details-internet-configure').hidden = false; 680 } else { 681 $('details-internet-configure').hidden = true; 682 } 683 }, 684 685 /** 686 * Helper method called from showDetailedInfo and updateConnectionData. 687 * Updates the connection state property and account / sim card links. 688 * @private 689 */ 690 updateDetails_: function() { 691 var onc = this.onc_; 692 693 var connectionStateString = onc.getTranslatedValue('ConnectionState'); 694 $('connection-state').textContent = connectionStateString; 695 696 var type = this.type_; 697 var showViewAccount = false; 698 var showActivate = false; 699 if (type == 'WiFi') { 700 $('wifi-connection-state').textContent = connectionStateString; 701 } else if (type == 'WiMAX') { 702 $('wimax-connection-state').textContent = connectionStateString; 703 } else if (type == 'Cellular') { 704 $('activation-state').textContent = 705 onc.getTranslatedValue('Cellular.ActivationState'); 706 if (onc.getActiveValue('Cellular.Family') == 'GSM') { 707 var lockEnabled = 708 onc.getActiveValue('Cellular.SIMLockStatus.LockEnabled'); 709 $('sim-card-lock-enabled').checked = lockEnabled; 710 $('change-pin').hidden = !lockEnabled; 711 } 712 showViewAccount = this.showViewAccountButton_; 713 var activationState = onc.getActiveValue('Cellular.ActivationState'); 714 showActivate = activationState == 'NotActivated' || 715 activationState == 'PartiallyActivated'; 716 } 717 718 $('view-account-details').hidden = !showViewAccount; 719 $('activate-details').hidden = !showActivate; 720 // If activation is not complete, hide the login button. 721 if (showActivate) 722 $('details-internet-login').hidden = true; 723 }, 724 725 /** 726 * Helper method called from showDetailedInfo and updateConnectionData. 727 * Updates the fields in the header section of the details frame. 728 * @private 729 */ 730 populateHeader_: function() { 731 var onc = this.onc_; 732 733 $('network-details-title').textContent = onc.getTranslatedValue('Name'); 734 var connectionState = onc.getActiveValue('ConnectionState'); 735 var connectionStateString = onc.getTranslatedValue('ConnectionState'); 736 $('network-details-subtitle-status').textContent = connectionStateString; 737 738 var typeKey; 739 var type = this.type_; 740 if (type == 'Ethernet') 741 typeKey = 'ethernetTitle'; 742 else if (type == 'WiFi') 743 typeKey = 'wifiTitle'; 744 else if (type == 'WiMAX') 745 typeKey = 'wimaxTitle'; 746 else if (type == 'Cellular') 747 typeKey = 'cellularTitle'; 748 else if (type == 'VPN') 749 typeKey = 'vpnTitle'; 750 else 751 typeKey = null; 752 var typeLabel = $('network-details-subtitle-type'); 753 var typeSeparator = $('network-details-subtitle-separator'); 754 if (typeKey) { 755 typeLabel.textContent = loadTimeData.getString(typeKey); 756 typeLabel.hidden = false; 757 typeSeparator.hidden = false; 758 } else { 759 typeLabel.hidden = true; 760 typeSeparator.hidden = true; 761 } 762 }, 763 764 /** 765 * Helper method called from showDetailedInfo to initialize the Apn list. 766 * @private 767 */ 768 initializeApnList_: function() { 769 var onc = this.onc_; 770 771 var apnSelector = $('select-apn'); 772 // Clear APN lists, keep only last element that "other". 773 while (apnSelector.length != 1) { 774 apnSelector.remove(0); 775 } 776 var otherOption = apnSelector[0]; 777 var activeApn = onc.getActiveValue('Cellular.APN.AccessPointName'); 778 var activeUsername = onc.getActiveValue('Cellular.APN.Username'); 779 var activePassword = onc.getActiveValue('Cellular.APN.Password'); 780 var lastGoodApn = 781 onc.getActiveValue('Cellular.LastGoodAPN.AccessPointName'); 782 var lastGoodUsername = 783 onc.getActiveValue('Cellular.LastGoodAPN.Username'); 784 var lastGoodPassword = 785 onc.getActiveValue('Cellular.LastGoodAPN.Password'); 786 var apnList = onc.getActiveValue('Cellular.APNList'); 787 for (var i = 0; i < apnList.length; i++) { 788 var apnDict = apnList[i]; 789 var option = document.createElement('option'); 790 var localizedName = apnDict['LocalizedName']; 791 var name = localizedName ? localizedName : apnDict['Name']; 792 var accessPointName = apnDict['AccessPointName']; 793 option.textContent = 794 name ? (name + ' (' + accessPointName + ')') : accessPointName; 795 option.value = i; 796 // Insert new option before "other" option. 797 apnSelector.add(option, otherOption); 798 if (this.selectedApnIndex_ != -1) 799 continue; 800 // If this matches the active Apn, or LastGoodApn (or there is no last 801 // good APN), set it as the selected Apn. 802 if ((activeApn == accessPointName && 803 activeUsername == apnDict['Username'] && 804 activePassword == apnDict['Password']) || 805 (!activeApn && !lastGoodApn) || 806 (!activeApn && 807 lastGoodApn == accessPointName && 808 lastGoodUsername == apnDict['Username'] && 809 lastGoodPassword == apnDict['Password'])) { 810 this.selectedApnIndex_ = i; 811 } 812 } 813 if (this.selectedApnIndex_ == -1 && activeApn) { 814 var activeOption = document.createElement('option'); 815 activeOption.textContent = activeApn; 816 activeOption.value = -1; 817 apnSelector.add(activeOption, otherOption); 818 this.selectedApnIndex_ = apnSelector.length - 2; 819 this.userApnIndex_ = this.selectedApnIndex_; 820 } 821 assert(this.selectedApnIndex_ >= 0); 822 apnSelector.selectedIndex = this.selectedApnIndex_; 823 updateHidden('.apn-list-view', false); 824 updateHidden('.apn-details-view', true); 825 }, 826 827 /** 828 * Event Listener for the cellular-apn-use-default button. 829 * @private 830 */ 831 setDefaultApn_: function() { 832 var onc = this.onc_; 833 var apnSelector = $('select-apn'); 834 835 if (this.userApnIndex_ != -1) { 836 apnSelector.remove(this.userApnIndex_); 837 this.userApnIndex_ = -1; 838 } 839 840 var iApn = -1; 841 var apnList = onc.getActiveValue('Cellular.APNList'); 842 if (apnList != undefined && apnList.length > 0) { 843 iApn = 0; 844 var defaultApn = apnList[iApn]; 845 var activeApn = {}; 846 activeApn['AccessPointName'] = 847 stringFromValue(defaultApn['AccessPointName']); 848 activeApn['Username'] = stringFromValue(defaultApn['Username']); 849 activeApn['Password'] = stringFromValue(defaultApn['Password']); 850 onc.setManagedProperty('Cellular.APN', activeApn); 851 chrome.send('setApn', [this.servicePath_, 852 activeApn['AccessPointName'], 853 activeApn['Username'], 854 activeApn['Password']]); 855 } 856 apnSelector.selectedIndex = iApn; 857 this.selectedApnIndex_ = iApn; 858 859 updateHidden('.apn-list-view', false); 860 updateHidden('.apn-details-view', true); 861 }, 862 863 /** 864 * Event Listener for the cellular-apn-set button. 865 * @private 866 */ 867 setApn_: function(apnValue) { 868 if (apnValue == '') 869 return; 870 871 var onc = this.onc_; 872 var apnSelector = $('select-apn'); 873 874 var activeApn = {}; 875 activeApn['AccessPointName'] = stringFromValue(apnValue); 876 activeApn['Username'] = stringFromValue($('cellular-apn-username').value); 877 activeApn['Password'] = stringFromValue($('cellular-apn-password').value); 878 onc.setManagedProperty('Cellular.APN', activeApn); 879 this.userApn_ = activeApn; 880 chrome.send('setApn', [this.servicePath_, 881 activeApn['AccessPointName'], 882 activeApn['Username'], 883 activeApn['Password']]); 884 885 if (this.userApnIndex_ != -1) { 886 apnSelector.remove(this.userApnIndex_); 887 this.userApnIndex_ = -1; 888 } 889 890 var option = document.createElement('option'); 891 option.textContent = activeApn['AccessPointName']; 892 option.value = -1; 893 option.selected = true; 894 apnSelector.add(option, apnSelector[apnSelector.length - 1]); 895 this.userApnIndex_ = apnSelector.length - 2; 896 this.selectedApnIndex_ = this.userApnIndex_; 897 898 updateHidden('.apn-list-view', false); 899 updateHidden('.apn-details-view', true); 900 }, 901 902 /** 903 * Event Listener for the cellular-apn-cancel button. 904 * @private 905 */ 906 cancelApn_: function() { 907 $('select-apn').selectedIndex = this.selectedApnIndex_; 908 updateHidden('.apn-list-view', false); 909 updateHidden('.apn-details-view', true); 910 }, 911 912 /** 913 * Event Listener for the select-apn button. 914 * @private 915 */ 916 selectApn_: function() { 917 var onc = this.onc_; 918 var apnSelector = $('select-apn'); 919 var apnDict; 920 if (apnSelector[apnSelector.selectedIndex].value != -1) { 921 var apnList = onc.getActiveValue('Cellular.APNList'); 922 var apnIndex = apnSelector.selectedIndex; 923 assert(apnIndex < apnList.length); 924 apnDict = apnList[apnIndex]; 925 chrome.send('setApn', [this.servicePath_, 926 stringFromValue(apnDict['AccessPointName']), 927 stringFromValue(apnDict['Username']), 928 stringFromValue(apnDict['Password'])]); 929 this.selectedApnIndex_ = apnIndex; 930 } else if (apnSelector.selectedIndex == this.userApnIndex_) { 931 apnDict = this.userApn_; 932 chrome.send('setApn', [this.servicePath_, 933 stringFromValue(apnDict['AccessPointName']), 934 stringFromValue(apnDict['Username']), 935 stringFromValue(apnDict['Password'])]); 936 this.selectedApnIndex_ = apnSelector.selectedIndex; 937 } else { 938 $('cellular-apn').value = 939 stringFromValue(onc.getActiveValue('Cellular.APN.AccessPointName')); 940 $('cellular-apn-username').value = 941 stringFromValue(onc.getActiveValue('Cellular.APN.Username')); 942 $('cellular-apn-password').value = 943 stringFromValue(onc.getActiveValue('Cellular.APN.Password')); 944 updateHidden('.apn-list-view', true); 945 updateHidden('.apn-details-view', false); 946 } 947 } 948 }; 949 950 /** 951 * Enables or Disables all buttons that provide operations on the cellular 952 * network. 953 */ 954 DetailsInternetPage.changeCellularButtonsState = function(disable) { 955 var buttonsToDisableList = 956 new Array('details-internet-login', 957 'details-internet-disconnect', 958 'details-internet-configure', 959 'activate-details', 960 'view-account-details'); 961 962 for (var i = 0; i < buttonsToDisableList.length; ++i) { 963 var button = $(buttonsToDisableList[i]); 964 button.disabled = disable; 965 } 966 }; 967 968 /** 969 * Shows a spinner while the carrier is changed. 970 */ 971 DetailsInternetPage.showCarrierChangeSpinner = function(visible) { 972 $('switch-carrier-spinner').hidden = !visible; 973 // Disable any buttons that allow us to operate on cellular networks. 974 DetailsInternetPage.changeCellularButtonsState(visible); 975 }; 976 977 /** 978 * Changes the network carrier. 979 */ 980 DetailsInternetPage.handleCarrierChanged = function() { 981 var carrierSelector = $('select-carrier'); 982 var carrier = carrierSelector[carrierSelector.selectedIndex].textContent; 983 DetailsInternetPage.showCarrierChangeSpinner(true); 984 chrome.send('setCarrier', [ 985 DetailsInternetPage.getInstance().servicePath_, carrier]); 986 }; 987 988 /** 989 * Performs minimal initialization of the InternetDetails dialog in 990 * preparation for showing proxy-settings. 991 */ 992 DetailsInternetPage.initializeProxySettings = function() { 993 DetailsInternetPage.getInstance().initializePageContents_(); 994 }; 995 996 /** 997 * Displays the InternetDetails dialog with only the proxy settings visible. 998 */ 999 DetailsInternetPage.showProxySettings = function() { 1000 var detailsPage = DetailsInternetPage.getInstance(); 1001 $('network-details-header').hidden = true; 1002 $('activate-details').hidden = true; 1003 $('view-account-details').hidden = true; 1004 $('web-proxy-auto-discovery').hidden = true; 1005 detailsPage.showProxy_ = true; 1006 updateHidden('#internet-tab', true); 1007 updateHidden('#details-tab-strip', true); 1008 updateHidden('#details-internet-page .action-area', true); 1009 detailsPage.updateControls(); 1010 detailsPage.visible = true; 1011 sendChromeMetricsAction('Options_NetworkShowProxyTab'); 1012 }; 1013 1014 /** 1015 * Initializes even handling for keyboard driven flow. 1016 */ 1017 DetailsInternetPage.initializeKeyboardFlow = function() { 1018 keyboard.initializeKeyboardFlow(); 1019 }; 1020 1021 DetailsInternetPage.updateProxySettings = function(type) { 1022 var proxyHost = null, 1023 proxyPort = null; 1024 1025 if (type == 'cros.session.proxy.singlehttp') { 1026 proxyHost = 'proxy-host-single-name'; 1027 proxyPort = 'proxy-host-single-port'; 1028 } else if (type == 'cros.session.proxy.httpurl') { 1029 proxyHost = 'proxy-host-name'; 1030 proxyPort = 'proxy-host-port'; 1031 } else if (type == 'cros.session.proxy.httpsurl') { 1032 proxyHost = 'secure-proxy-host-name'; 1033 proxyPort = 'secure-proxy-port'; 1034 } else if (type == 'cros.session.proxy.ftpurl') { 1035 proxyHost = 'ftp-proxy'; 1036 proxyPort = 'ftp-proxy-port'; 1037 } else if (type == 'cros.session.proxy.socks') { 1038 proxyHost = 'socks-host'; 1039 proxyPort = 'socks-port'; 1040 } else { 1041 return; 1042 } 1043 1044 var hostValue = $(proxyHost).value; 1045 if (hostValue.indexOf(':') !== -1) { 1046 if (hostValue.match(/:/g).length == 1) { 1047 hostValue = hostValue.split(':'); 1048 $(proxyHost).value = hostValue[0]; 1049 $(proxyPort).value = hostValue[1]; 1050 } 1051 } 1052 }; 1053 1054 DetailsInternetPage.updateCarrier = function() { 1055 DetailsInternetPage.showCarrierChangeSpinner(false); 1056 }; 1057 1058 DetailsInternetPage.loginFromDetails = function() { 1059 var detailsPage = DetailsInternetPage.getInstance(); 1060 if (detailsPage.type_ == 'WiFi') 1061 sendChromeMetricsAction('Options_NetworkConnectToWifi'); 1062 else if (detailsPage.type_ == 'VPN') 1063 sendChromeMetricsAction('Options_NetworkConnectToVPN'); 1064 // TODO(stevenjb): chrome.networkingPrivate.disableNetworkType 1065 chrome.send('startConnect', [detailsPage.servicePath_]); 1066 PageManager.closeOverlay(); 1067 }; 1068 1069 DetailsInternetPage.disconnectNetwork = function() { 1070 var detailsPage = DetailsInternetPage.getInstance(); 1071 if (detailsPage.type_ == 'WiFi') 1072 sendChromeMetricsAction('Options_NetworkDisconnectWifi'); 1073 else if (detailsPage.type_ == 'VPN') 1074 sendChromeMetricsAction('Options_NetworkDisconnectVPN'); 1075 // TODO(stevenjb): chrome.networkingPrivate.startDisconnect 1076 chrome.send('startDisconnect', [detailsPage.servicePath_]); 1077 PageManager.closeOverlay(); 1078 }; 1079 1080 DetailsInternetPage.configureNetwork = function() { 1081 var detailsPage = DetailsInternetPage.getInstance(); 1082 chrome.send('networkCommand', 1083 [detailsPage.type_, detailsPage.servicePath_, 'configure']); 1084 PageManager.closeOverlay(); 1085 }; 1086 1087 DetailsInternetPage.activateFromDetails = function() { 1088 var detailsPage = DetailsInternetPage.getInstance(); 1089 if (detailsPage.type_ == 'Cellular') { 1090 chrome.send('networkCommand', 1091 [detailsPage.type_, detailsPage.servicePath_, 'activate']); 1092 } 1093 PageManager.closeOverlay(); 1094 }; 1095 1096 /** 1097 * Event handler called when the details page is closed. Sends changed 1098 * properties to Chrome and closes the overlay. 1099 */ 1100 DetailsInternetPage.setDetails = function() { 1101 var detailsPage = DetailsInternetPage.getInstance(); 1102 var type = detailsPage.type_; 1103 var servicePath = detailsPage.servicePath_; 1104 if (type == 'WiFi') { 1105 sendCheckedIfEnabled(servicePath, 1106 'setPreferNetwork', 1107 'prefer-network-wifi', 1108 'Options_NetworkSetPrefer'); 1109 sendCheckedIfEnabled(servicePath, 1110 'setAutoConnect', 1111 'auto-connect-network-wifi', 1112 'Options_NetworkAutoConnect'); 1113 } else if (type == 'WiMAX') { 1114 sendCheckedIfEnabled(servicePath, 1115 'setAutoConnect', 1116 'auto-connect-network-wimax', 1117 'Options_NetworkAutoConnect'); 1118 } else if (type == 'Cellular') { 1119 sendCheckedIfEnabled(servicePath, 1120 'setAutoConnect', 1121 'auto-connect-network-cellular', 1122 'Options_NetworkAutoConnect'); 1123 } else if (type == 'VPN') { 1124 chrome.send('setServerHostname', 1125 [servicePath, $('inet-server-hostname').value]); 1126 sendCheckedIfEnabled(servicePath, 1127 'setAutoConnect', 1128 'auto-connect-network-vpn', 1129 'Options_NetworkAutoConnect'); 1130 } 1131 1132 var nameServerTypes = ['automatic', 'google', 'user']; 1133 var nameServerType = 'automatic'; 1134 for (var i = 0; i < nameServerTypes.length; ++i) { 1135 if ($(nameServerTypes[i] + '-dns-radio').checked) { 1136 nameServerType = nameServerTypes[i]; 1137 break; 1138 } 1139 } 1140 detailsPage.sendIpConfig_(nameServerType); 1141 1142 PageManager.closeOverlay(); 1143 }; 1144 1145 /** 1146 * Event handler called when the name server type changes. 1147 * @param {string} type The selected name sever type, 'automatic', 'google', 1148 * or 'user'. 1149 */ 1150 DetailsInternetPage.updateNameServerDisplay = function(type) { 1151 var editable = type == 'user'; 1152 var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'), 1153 $('ipconfig-dns3'), $('ipconfig-dns4')]; 1154 for (var i = 0; i < fields.length; ++i) { 1155 fields[i].editable = editable; 1156 } 1157 if (editable) 1158 $('ipconfig-dns1').focus(); 1159 1160 var automaticDns = $('automatic-dns-display'); 1161 var googleDns = $('google-dns-display'); 1162 var userDns = $('user-dns-settings'); 1163 switch (type) { 1164 case 'automatic': 1165 automaticDns.setAttribute('selected', ''); 1166 googleDns.removeAttribute('selected'); 1167 userDns.removeAttribute('selected'); 1168 break; 1169 case 'google': 1170 automaticDns.removeAttribute('selected'); 1171 googleDns.setAttribute('selected', ''); 1172 userDns.removeAttribute('selected'); 1173 break; 1174 case 'user': 1175 automaticDns.removeAttribute('selected'); 1176 googleDns.removeAttribute('selected'); 1177 userDns.setAttribute('selected', ''); 1178 break; 1179 } 1180 }; 1181 1182 /** 1183 * Method called from Chrome with a dictionary of non ONC configuration 1184 * properties, including the HUID and service path to be used for requesting 1185 * the ONC properties. Note: currently GUID is only used to confirm that the 1186 * selected network still exists. It will be used instead of servicePath 1187 * once switching to the networkingPrivate API (see TODO below). 1188 * @param {InternetDetailedInfo} info 1189 */ 1190 DetailsInternetPage.showDetailedInfo = function(info) { 1191 if (!('GUID' in info)) { 1192 // No network was found for, close the overlay. 1193 PageManager.closeOverlay(); 1194 return; 1195 } 1196 var detailsPage = DetailsInternetPage.getInstance(); 1197 detailsPage.servicePath_ = info.servicePath; 1198 detailsPage.showCarrierSelect_ = info.showCarrierSelect; 1199 detailsPage.showViewAccountButton_ = info.showViewAccountButton; 1200 // Ask Chrome to call sendNetworkDetails with the ONC properties. 1201 // TODO(stevenjb): Use networkingPrivate.getManagedProperties(info.guid). 1202 chrome.send('getManagedProperties', [info.servicePath]); 1203 }; 1204 1205 /** 1206 * Method called from Chrome when the ONC properties for the displayed 1207 * network may have changed. 1208 * @param {Object} update The updated ONC dictionary for the network. 1209 */ 1210 DetailsInternetPage.updateConnectionData = function(oncData) { 1211 var detailsPage = DetailsInternetPage.getInstance(); 1212 if (!detailsPage.visible) 1213 return; 1214 1215 if (oncData.servicePath != detailsPage.servicePath_) 1216 return; 1217 1218 // Update our cached data object. 1219 detailsPage.onc_ = new OncData(oncData); 1220 1221 detailsPage.populateHeader_(); 1222 detailsPage.updateConnectionButtonVisibilty_(); 1223 detailsPage.updateDetails_(); 1224 }; 1225 1226 /** 1227 * Method called from Chrome when the initial dictionary of ONC configuration 1228 * properties is available. 1229 * @param {Object} oncData Dictionary of ONC properties. 1230 */ 1231 DetailsInternetPage.sendNetworkDetails = function(oncData) { 1232 var onc = new OncData(oncData); 1233 1234 var detailsPage = DetailsInternetPage.getInstance(); 1235 detailsPage.onc_ = onc; 1236 var type = onc.getActiveValue('Type'); 1237 detailsPage.type_ = type; 1238 1239 sendShowDetailsMetrics(type, onc.getActiveValue('ConnectionState')); 1240 1241 detailsPage.populateHeader_(); 1242 detailsPage.updateConnectionButtonVisibilty_(); 1243 detailsPage.updateDetails_(); 1244 1245 // TODO(stevenjb): Some of the setup below should be moved to 1246 // updateDetails_() so that updates are reflected in the UI. 1247 1248 // Only show proxy for remembered networks. 1249 var remembered = onc.getSource() != 'None'; 1250 if (remembered) { 1251 detailsPage.showProxy_ = true; 1252 // Inform Chrome which network to use for proxy configuration. 1253 chrome.send('selectNetwork', [detailsPage.servicePath_]); 1254 } else { 1255 detailsPage.showProxy_ = false; 1256 } 1257 1258 $('web-proxy-auto-discovery').hidden = true; 1259 1260 var restricted = onc.getActiveValue('RestrictedConnectivity'); 1261 var restrictedString = loadTimeData.getString( 1262 restricted ? 'restrictedYes' : 'restrictedNo'); 1263 1264 var inetAddress = {}; 1265 var inetNetmask = {}; 1266 var inetGateway = {}; 1267 1268 var inetNameServersString; 1269 1270 var ipconfigList = onc.getActiveValue('IPConfigs'); 1271 if (Array.isArray(ipconfigList)) { 1272 for (var i = 0; i < ipconfigList.length; ++i) { 1273 var ipconfig = ipconfigList[i]; 1274 var ipType = ipconfig['Type']; 1275 if (ipType != 'IPv4') { 1276 // TODO(stevenjb): Handle IPv6 properties. 1277 continue; 1278 } 1279 var address = ipconfig['IPAddress']; 1280 inetAddress.automatic = address; 1281 inetAddress.value = address; 1282 var netmask = prefixLengthToNetmask(ipconfig['RoutingPrefix']); 1283 inetNetmask.automatic = netmask; 1284 inetNetmask.value = netmask; 1285 var gateway = ipconfig['Gateway']; 1286 inetGateway.automatic = gateway; 1287 inetGateway.value = gateway; 1288 if ('WebProxyAutoDiscoveryUrl' in ipconfig) { 1289 $('web-proxy-auto-discovery').hidden = false; 1290 $('web-proxy-auto-discovery-url').value = 1291 ipconfig['WebProxyAutoDiscoveryUrl']; 1292 } 1293 if ('NameServers' in ipconfig) { 1294 var inetNameServers = ipconfig['NameServers']; 1295 inetNameServers = inetNameServers.sort(); 1296 inetNameServersString = inetNameServers.join(','); 1297 } 1298 break; // Use the first IPv4 entry. 1299 } 1300 } 1301 1302 // Override the "automatic" values with the real saved DHCP values, 1303 // if they are set. 1304 var savedNameServersString; 1305 var savedIpAddress = onc.getActiveValue('SavedIPConfig.IPAddress'); 1306 if (savedIpAddress != undefined) { 1307 inetAddress.automatic = savedIpAddress; 1308 inetAddress.value = savedIpAddress; 1309 } 1310 var savedPrefix = onc.getActiveValue('SavedIPConfig.RoutingPrefix'); 1311 if (savedPrefix != undefined) { 1312 var savedNetmask = prefixLengthToNetmask(savedPrefix); 1313 inetNetmask.automatic = savedNetmask; 1314 inetNetmask.value = savedNetmask; 1315 } 1316 var savedGateway = onc.getActiveValue('SavedIPConfig.Gateway'); 1317 if (savedGateway != undefined) { 1318 inetGateway.automatic = savedGateway; 1319 inetGateway.value = savedGateway; 1320 } 1321 var savedNameServers = onc.getActiveValue('SavedIPConfig.NameServers'); 1322 if (savedNameServers) { 1323 savedNameServers = savedNameServers.sort(); 1324 savedNameServersString = savedNameServers.join(','); 1325 } 1326 1327 var ipAutoConfig = 'automatic'; 1328 1329 var staticNameServersString; 1330 var staticIpAddress = onc.getActiveValue('StaticIPConfig.IPAddress'); 1331 if (staticIpAddress != undefined) { 1332 ipAutoConfig = 'user'; 1333 inetAddress.user = staticIpAddress; 1334 inetAddress.value = staticIpAddress; 1335 } 1336 var staticPrefix = onc.getActiveValue('StaticIPConfig.RoutingPrefix'); 1337 if (staticPrefix != undefined) { 1338 var staticNetmask = prefixLengthToNetmask(staticPrefix); 1339 inetNetmask.user = staticNetmask; 1340 inetNetmask.value = staticNetmask; 1341 } 1342 var staticGateway = onc.getActiveValue('StaticIPConfig.Gateway'); 1343 if (staticGateway != undefined) { 1344 inetGateway.user = staticGateway; 1345 inetGateway.value = staticGateway; 1346 } 1347 var staticNameServers = onc.getActiveValue('StaticIPConfig.NameServers'); 1348 if (staticNameServers) { 1349 staticNameServers = staticNameServers.sort(); 1350 staticNameServersString = staticNameServers.join(','); 1351 } 1352 1353 $('ip-automatic-configuration-checkbox').checked = 1354 ipAutoConfig == 'automatic'; 1355 1356 inetAddress.autoConfig = ipAutoConfig; 1357 inetNetmask.autoConfig = ipAutoConfig; 1358 inetGateway.autoConfig = ipAutoConfig; 1359 1360 var configureAddressField = function(field, model) { 1361 IPAddressField.decorate(field); 1362 field.model = model; 1363 field.editable = model.autoConfig == 'user'; 1364 }; 1365 configureAddressField($('ip-address'), inetAddress); 1366 configureAddressField($('ip-netmask'), inetNetmask); 1367 configureAddressField($('ip-gateway'), inetGateway); 1368 1369 // Set Nameserver fields. 1370 var nameServerType = 'automatic'; 1371 if (staticNameServersString) { 1372 // If static nameservers are defined and match the google name servers, 1373 // show that in the UI, otherwise show the custom static nameservers. 1374 if (staticNameServersString == GoogleNameServersString) 1375 nameServerType = 'google'; 1376 else if (staticNameServersString == inetNameServersString) 1377 nameServerType = 'user'; 1378 } 1379 if (nameServerType == 'automatic') 1380 $('automatic-dns-display').textContent = inetNameServersString; 1381 else 1382 $('automatic-dns-display').textContent = savedNameServersString; 1383 $('google-dns-display').textContent = GoogleNameServersString; 1384 1385 var nameServersUser = []; 1386 if (staticNameServers) { 1387 nameServersUser = staticNameServers; 1388 } else if (savedNameServers) { 1389 // Pre-populate with values provided by DHCP server. 1390 nameServersUser = savedNameServers; 1391 } 1392 1393 var nameServerModels = []; 1394 for (var i = 0; i < 4; ++i) 1395 nameServerModels.push({value: nameServersUser[i] || ''}); 1396 1397 $(nameServerType + '-dns-radio').checked = true; 1398 configureAddressField($('ipconfig-dns1'), nameServerModels[0]); 1399 configureAddressField($('ipconfig-dns2'), nameServerModels[1]); 1400 configureAddressField($('ipconfig-dns3'), nameServerModels[2]); 1401 configureAddressField($('ipconfig-dns4'), nameServerModels[3]); 1402 1403 DetailsInternetPage.updateNameServerDisplay(nameServerType); 1404 1405 var macAddress = onc.getActiveValue('MacAddress'); 1406 if (macAddress) { 1407 $('hardware-address').textContent = macAddress; 1408 $('hardware-address-row').style.display = 'table-row'; 1409 } else { 1410 // This is most likely a device without a hardware address. 1411 $('hardware-address-row').style.display = 'none'; 1412 } 1413 1414 var setOrHideParent = function(field, property) { 1415 if (property != undefined) { 1416 $(field).textContent = property; 1417 $(field).parentElement.hidden = false; 1418 } else { 1419 $(field).parentElement.hidden = true; 1420 } 1421 }; 1422 1423 var networkName = onc.getTranslatedValue('Name'); 1424 1425 // Signal strength as percentage (for WiFi and WiMAX). 1426 var signalStrength; 1427 if (type == 'WiFi' || type == 'WiMAX') 1428 signalStrength = onc.getActiveValue(type + '.SignalStrength'); 1429 if (!signalStrength) 1430 signalStrength = 0; 1431 var strengthFormat = loadTimeData.getString('inetSignalStrengthFormat'); 1432 var strengthString = strengthFormat.replace('$1', signalStrength); 1433 1434 if (type == 'WiFi') { 1435 OptionsPage.showTab($('wifi-network-nav-tab')); 1436 $('wifi-restricted-connectivity').textContent = restrictedString; 1437 var ssid = onc.getActiveValue('WiFi.SSID'); 1438 $('wifi-ssid').textContent = ssid ? ssid : networkName; 1439 setOrHideParent('wifi-bssid', onc.getActiveValue('WiFi.BSSID')); 1440 var security = onc.getWiFiSecurity(); 1441 if (security == 'None') 1442 security = undefined; 1443 setOrHideParent('wifi-security', security); 1444 // Frequency is in MHz. 1445 var frequency = onc.getActiveValue('WiFi.Frequency'); 1446 if (!frequency) 1447 frequency = 0; 1448 var frequencyFormat = loadTimeData.getString('inetFrequencyFormat'); 1449 frequencyFormat = frequencyFormat.replace('$1', frequency); 1450 $('wifi-frequency').textContent = frequencyFormat; 1451 $('wifi-signal-strength').textContent = strengthString; 1452 setOrHideParent('wifi-hardware-address', 1453 onc.getActiveValue('MacAddress')); 1454 var priority = onc.getActiveValue('Priority'); 1455 $('prefer-network-wifi').checked = priority > 0; 1456 $('prefer-network-wifi').disabled = !remembered; 1457 $('auto-connect-network-wifi').checked = 1458 onc.getActiveValue('WiFi.AutoConnect'); 1459 $('auto-connect-network-wifi').disabled = !remembered; 1460 } else if (type == 'WiMAX') { 1461 OptionsPage.showTab($('wimax-network-nav-tab')); 1462 $('wimax-restricted-connectivity').textContent = restrictedString; 1463 1464 $('auto-connect-network-wimax').checked = 1465 onc.getActiveValue('WiMAX.AutoConnect'); 1466 $('auto-connect-network-wimax').disabled = !remembered; 1467 var identity = onc.getActiveValue('WiMAX.EAP.Identity'); 1468 setOrHideParent('wimax-eap-identity', identity); 1469 $('wimax-signal-strength').textContent = strengthString; 1470 } else if (type == 'Cellular') { 1471 OptionsPage.showTab($('cellular-conn-nav-tab')); 1472 1473 var isGsm = onc.getActiveValue('Cellular.Family') == 'GSM'; 1474 1475 var currentCarrierIndex = -1; 1476 if (this.showCarrierSelect_) { 1477 var currentCarrier = 1478 isGsm ? CarrierGenericUMTS : onc.getActiveValue('Cellular.Carrier'); 1479 var supportedCarriers = 1480 onc.getActiveValue('Cellular.SupportedCarriers'); 1481 for (var c1 = 0; c1 < supportedCarriers.length; ++c1) { 1482 if (supportedCarriers[c1] == currentCarrier) { 1483 currentCarrierIndex = c1; 1484 break; 1485 } 1486 } 1487 if (currentCarrierIndex != -1) { 1488 var carrierSelector = $('select-carrier'); 1489 carrierSelector.onchange = DetailsInternetPage.handleCarrierChanged; 1490 carrierSelector.options.length = 0; 1491 for (var c2 = 0; c2 < supportedCarriers.length; ++c2) { 1492 var option = document.createElement('option'); 1493 option.textContent = supportedCarriers[c2]; 1494 carrierSelector.add(option); 1495 } 1496 carrierSelector.selectedIndex = currentCarrierIndex; 1497 } 1498 } 1499 if (currentCarrierIndex == -1) 1500 $('service-name').textContent = networkName; 1501 1502 $('network-technology').textContent = 1503 onc.getActiveValue('Cellular.NetworkTechnology'); 1504 $('roaming-state').textContent = 1505 onc.getTranslatedValue('Cellular.RoamingState'); 1506 $('cellular-restricted-connectivity').textContent = restrictedString; 1507 // 'errorMessage' is a non ONC property added by Chrome. 1508 $('error-state').textContent = onc.getActiveValue('errorMessage'); 1509 $('manufacturer').textContent = 1510 onc.getActiveValue('Cellular.Manufacturer'); 1511 $('model-id').textContent = onc.getActiveValue('Cellular.ModelID'); 1512 $('firmware-revision').textContent = 1513 onc.getActiveValue('Cellular.FirmwareRevision'); 1514 $('hardware-revision').textContent = 1515 onc.getActiveValue('Cellular.HardwareRevision'); 1516 $('mdn').textContent = onc.getActiveValue('Cellular.MDN'); 1517 1518 // Show ServingOperator properties only if available. 1519 var servingOperatorName = 1520 onc.getActiveValue('Cellular.ServingOperator.Name'); 1521 var servingOperatorCode = 1522 onc.getActiveValue('Cellular.ServingOperator.Code'); 1523 if (servingOperatorName != undefined && 1524 servingOperatorCode != undefined) { 1525 $('operator-name').textContent = servingOperatorName; 1526 $('operator-code').textContent = servingOperatorCode; 1527 } else { 1528 $('operator-name').parentElement.hidden = true; 1529 $('operator-code').parentElement.hidden = true; 1530 } 1531 // Make sure that GSM/CDMA specific properties that shouldn't be hidden 1532 // are visible. 1533 updateHidden('#details-internet-page .gsm-only', false); 1534 updateHidden('#details-internet-page .cdma-only', false); 1535 1536 // Show IMEI/ESN/MEID/MIN/PRL only if they are available. 1537 setOrHideParent('esn', onc.getActiveValue('Cellular.ESN')); 1538 setOrHideParent('imei', onc.getActiveValue('Cellular.IMEI')); 1539 setOrHideParent('meid', onc.getActiveValue('Cellular.MEID')); 1540 setOrHideParent('min', onc.getActiveValue('Cellular.MIN')); 1541 setOrHideParent('prl-version', onc.getActiveValue('Cellular.PRLVersion')); 1542 1543 if (isGsm) { 1544 $('iccid').textContent = onc.getActiveValue('Cellular.ICCID'); 1545 $('imsi').textContent = onc.getActiveValue('Cellular.IMSI'); 1546 detailsPage.initializeApnList_(); 1547 } 1548 $('auto-connect-network-cellular').checked = 1549 onc.getActiveValue('Cellular.AutoConnect'); 1550 $('auto-connect-network-cellular').disabled = false; 1551 } else if (type == 'VPN') { 1552 OptionsPage.showTab($('vpn-nav-tab')); 1553 $('inet-service-name').textContent = networkName; 1554 $('inet-provider-type').textContent = 1555 onc.getTranslatedValue('VPN.Type'); 1556 var providerType = onc.getActiveValue('VPN.Type'); 1557 var usernameKey; 1558 if (providerType == 'OpenVPN') 1559 usernameKey = 'VPN.OpenVPN.Username'; 1560 else if (providerType == 'L2TP-IPsec') 1561 usernameKey = 'VPN.L2TP.Username'; 1562 1563 if (usernameKey) { 1564 $('inet-username').parentElement.hidden = false; 1565 $('inet-username').textContent = onc.getActiveValue(usernameKey); 1566 } else { 1567 $('inet-username').parentElement.hidden = true; 1568 } 1569 var inetServerHostname = $('inet-server-hostname'); 1570 inetServerHostname.value = onc.getActiveValue('VPN.Host'); 1571 inetServerHostname.resetHandler = function() { 1572 PageManager.hideBubble(); 1573 var recommended = onc.getRecommendedValue('VPN.Host'); 1574 if (recommended != undefined) 1575 inetServerHostname.value = recommended; 1576 }; 1577 $('auto-connect-network-vpn').checked = 1578 onc.getActiveValue('VPN.AutoConnect'); 1579 $('auto-connect-network-vpn').disabled = false; 1580 } else { 1581 OptionsPage.showTab($('internet-nav-tab')); 1582 } 1583 1584 // Update controlled option indicators. 1585 var indicators = cr.doc.querySelectorAll( 1586 '#details-internet-page .controlled-setting-indicator'); 1587 for (var i = 0; i < indicators.length; i++) { 1588 var managed = indicators[i].hasAttribute('managed'); 1589 // TODO(stevenjb): Eliminate support for 'data' once 39 is stable. 1590 var attributeName = managed ? 'managed' : 'data'; 1591 var propName = indicators[i].getAttribute(attributeName); 1592 if (!propName) 1593 continue; 1594 var propValue = managed ? 1595 onc.getManagedProperty(propName) : 1596 onc.getActiveValue(propName); 1597 // If the property is unset or unmanaged (i.e. not an Object) skip it. 1598 if (propValue == undefined || (typeof propValue != 'object')) 1599 continue; 1600 var event; 1601 if (managed) 1602 event = detailsPage.createManagedEvent_(propName, propValue); 1603 else 1604 event = detailsPage.createControlledEvent_(propName, 1605 /** @type {{value: *, controlledBy: *, recommendedValue: *}} */( 1606 propValue)); 1607 indicators[i].handlePrefChange(event); 1608 var forElement = $(indicators[i].getAttribute('for')); 1609 if (forElement) { 1610 if (event.value.controlledBy == 'policy') 1611 forElement.disabled = true; 1612 if (forElement.resetHandler) 1613 indicators[i].resetHandler = forElement.resetHandler; 1614 } 1615 } 1616 1617 detailsPage.updateControls(); 1618 1619 // Don't show page name in address bar and in history to prevent people 1620 // navigate here by hand and solve issue with page session restore. 1621 PageManager.showPageByName('detailsInternetPage', false); 1622 }; 1623 1624 return { 1625 DetailsInternetPage: DetailsInternetPage 1626 }; 1627 }); 1628