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 cr.define('options.internet', function() { 6 var OptionsPage = options.OptionsPage; 7 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; 8 /** @const */ var IPAddressField = options.internet.IPAddressField; 9 10 /** 11 * Network settings constants. These enums must match their C++ 12 * counterparts. 13 */ 14 function Constants() {} 15 16 // Network types: 17 Constants.TYPE_UNKNOWN = 'UNKNOWN'; 18 Constants.TYPE_ETHERNET = 'ethernet'; 19 Constants.TYPE_WIFI = 'wifi'; 20 Constants.TYPE_WIMAX = 'wimax'; 21 Constants.TYPE_BLUETOOTH = 'bluetooth'; 22 Constants.TYPE_CELLULAR = 'cellular'; 23 Constants.TYPE_VPN = 'vpn'; 24 25 /* 26 * Helper function to set hidden attribute for elements matching a selector. 27 * @param {string} selector CSS selector for extracting a list of elements. 28 * @param {bool} hidden New hidden value. 29 */ 30 function updateHidden(selector, hidden) { 31 var elements = cr.doc.querySelectorAll(selector); 32 for (var i = 0, el; el = elements[i]; i++) { 33 el.hidden = hidden; 34 } 35 } 36 37 /* 38 * Helper function to update the properties of the data object from the 39 * properties in the update object. 40 * @param {object} data object to update. 41 * @param {object} object containing the updated properties. 42 */ 43 function updateDataObject(data, update) { 44 for (prop in update) { 45 if (prop in data) 46 data[prop] = update[prop]; 47 } 48 } 49 50 /** 51 * Monitor pref change of given element. 52 * @param {Element} el Target element. 53 */ 54 function observePrefsUI(el) { 55 Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate); 56 } 57 58 /** 59 * UI pref change handler. 60 * @param {Event} e The update event. 61 */ 62 function handlePrefUpdate(e) { 63 DetailsInternetPage.getInstance().updateControls(); 64 } 65 66 /** 67 * Simple helper method for converting a field to a string. It is used to 68 * easily assign an empty string from fields that may be unknown or undefined. 69 * @param {object} value that should be converted to a string. 70 * @return {string} the result. 71 */ 72 function stringFromValue(value) { 73 return value ? String(value) : ''; 74 } 75 76 /** 77 * Sends the 'checked' state of a control to chrome for a network. 78 * @param {string} path The service path of the network. 79 * @param {string} message The message to send to chrome. 80 * @param {HTMLInputElement} checkbox The checkbox storing the value to send. 81 */ 82 function sendCheckedIfEnabled(path, message, checkbox) { 83 if (!checkbox.hidden && !checkbox.disabled) 84 chrome.send(message, [path, checkbox.checked ? 'true' : 'false']); 85 } 86 87 ///////////////////////////////////////////////////////////////////////////// 88 // DetailsInternetPage class: 89 90 /** 91 * Encapsulated handling of ChromeOS internet details overlay page. 92 * @constructor 93 */ 94 function DetailsInternetPage() { 95 OptionsPage.call(this, 96 'detailsInternetPage', 97 null, 98 'details-internet-page'); 99 } 100 101 cr.addSingletonGetter(DetailsInternetPage); 102 103 DetailsInternetPage.prototype = { 104 __proto__: OptionsPage.prototype, 105 106 /** 107 * Initializes DetailsInternetPage page. 108 * Calls base class implementation to starts preference initialization. 109 */ 110 initializePage: function() { 111 OptionsPage.prototype.initializePage.call(this); 112 var params = parseQueryParams(window.location); 113 this.initializePageContents_(params); 114 this.showNetworkDetails_(params); 115 }, 116 117 /** 118 * Auto-activates the network details dialog if network information 119 * is included in the URL. 120 */ 121 showNetworkDetails_: function(params) { 122 var servicePath = params.servicePath; 123 if (!servicePath || !servicePath.length) 124 return; 125 var networkType = ''; // ignored for 'options' 126 chrome.send('networkCommand', [networkType, servicePath, 'options']); 127 }, 128 129 130 /** 131 * Initializes the contents of the page. 132 */ 133 initializePageContents_: function(params) { 134 $('details-internet-dismiss').addEventListener('click', function(event) { 135 DetailsInternetPage.setDetails(); 136 }); 137 138 $('details-internet-login').addEventListener('click', function(event) { 139 DetailsInternetPage.setDetails(); 140 DetailsInternetPage.loginFromDetails(); 141 }); 142 143 $('details-internet-disconnect').addEventListener('click', 144 function(event) { 145 DetailsInternetPage.setDetails(); 146 DetailsInternetPage.disconnectNetwork(); 147 }); 148 149 $('details-internet-configure').addEventListener('click', 150 function(event) { 151 DetailsInternetPage.setDetails(); 152 DetailsInternetPage.configureNetwork(); 153 }); 154 155 $('activate-details').addEventListener('click', function(event) { 156 DetailsInternetPage.activateFromDetails(); 157 }); 158 159 $('buyplan-details').addEventListener('click', function(event) { 160 var data = $('connection-state').data; 161 chrome.send('buyDataPlan', [data.servicePath]); 162 OptionsPage.closeOverlay(); 163 }); 164 165 $('view-account-details').addEventListener('click', function(event) { 166 var data = $('connection-state').data; 167 chrome.send('showMorePlanInfo', [data.servicePath]); 168 OptionsPage.closeOverlay(); 169 }); 170 171 $('cellular-apn-use-default').addEventListener('click', function(event) { 172 var data = $('connection-state').data; 173 var apnSelector = $('select-apn'); 174 175 if (data.userApnIndex != -1) { 176 apnSelector.remove(data.userApnIndex); 177 data.userApnIndex = -1; 178 } 179 180 if (data.providerApnList.value.length > 0) { 181 var iApn = 0; 182 var defaultApn = data.providerApnList.value[iApn]; 183 data.apn.apn = stringFromValue(defaultApn.apn); 184 data.apn.username = stringFromValue(defaultApn.username); 185 data.apn.password = stringFromValue(defaultApn.password); 186 chrome.send('setApn', [data.servicePath, 187 data.apn.apn, 188 data.apn.username, 189 data.apn.password]); 190 apnSelector.selectedIndex = iApn; 191 data.selectedApn = iApn; 192 } else { 193 data.apn.apn = ''; 194 data.apn.username = ''; 195 data.apn.password = ''; 196 apnSelector.selectedIndex = -1; 197 data.selectedApn = -1; 198 } 199 updateHidden('.apn-list-view', false); 200 updateHidden('.apn-details-view', true); 201 }); 202 203 $('cellular-apn-set').addEventListener('click', function(event) { 204 if ($('cellular-apn').value == '') 205 return; 206 207 var data = $('connection-state').data; 208 var apnSelector = $('select-apn'); 209 210 data.apn.apn = stringFromValue($('cellular-apn').value); 211 data.apn.username = stringFromValue($('cellular-apn-username').value); 212 data.apn.password = stringFromValue($('cellular-apn-password').value); 213 data.userApn = { 214 'apn': data.apn.apn, 215 'username': data.apn.username, 216 'password': data.apn.password 217 }; 218 chrome.send('setApn', [data.servicePath, 219 data.apn.apn, 220 data.apn.username, 221 data.apn.password]); 222 223 if (data.userApnIndex != -1) { 224 apnSelector.remove(data.userApnIndex); 225 data.userApnIndex = -1; 226 } 227 228 var option = document.createElement('option'); 229 option.textContent = data.apn.apn; 230 option.value = -1; 231 option.selected = true; 232 apnSelector.add(option, apnSelector[apnSelector.length - 1]); 233 data.userApnIndex = apnSelector.length - 2; 234 data.selectedApn = data.userApnIndex; 235 236 updateHidden('.apn-list-view', false); 237 updateHidden('.apn-details-view', true); 238 }); 239 240 $('cellular-apn-cancel').addEventListener('click', function(event) { 241 $('select-apn').selectedIndex = $('connection-state').data.selectedApn; 242 updateHidden('.apn-list-view', false); 243 updateHidden('.apn-details-view', true); 244 }); 245 246 $('select-apn').addEventListener('change', function(event) { 247 var data = $('connection-state').data; 248 var apnSelector = $('select-apn'); 249 if (apnSelector[apnSelector.selectedIndex].value != -1) { 250 var apnList = data.providerApnList.value; 251 chrome.send('setApn', [data.servicePath, 252 stringFromValue(apnList[apnSelector.selectedIndex].apn), 253 stringFromValue(apnList[apnSelector.selectedIndex].username), 254 stringFromValue(apnList[apnSelector.selectedIndex].password)] 255 ); 256 data.selectedApn = apnSelector.selectedIndex; 257 } else if (apnSelector.selectedIndex == data.userApnIndex) { 258 chrome.send('setApn', [data.servicePath, 259 stringFromValue(data.userApn.apn), 260 stringFromValue(data.userApn.username), 261 stringFromValue(data.userApn.password)]); 262 data.selectedApn = apnSelector.selectedIndex; 263 } else { 264 $('cellular-apn').value = stringFromValue(data.apn.apn); 265 $('cellular-apn-username').value = stringFromValue(data.apn.username); 266 $('cellular-apn-password').value = stringFromValue(data.apn.password); 267 268 updateHidden('.apn-list-view', true); 269 updateHidden('.apn-details-view', false); 270 } 271 }); 272 273 $('sim-card-lock-enabled').addEventListener('click', function(event) { 274 var newValue = $('sim-card-lock-enabled').checked; 275 // Leave value as is because user needs to enter PIN code first. 276 // When PIN will be entered and value changed, 277 // we'll update UI to reflect that change. 278 $('sim-card-lock-enabled').checked = !newValue; 279 chrome.send('setSimCardLock', [newValue]); 280 }); 281 $('change-pin').addEventListener('click', function(event) { 282 chrome.send('changePin'); 283 }); 284 285 // Proxy 286 ['proxy-host-single-port', 287 'secure-proxy-port', 288 'socks-port', 289 'ftp-proxy-port', 290 'proxy-host-port' 291 ].forEach(function(id) { 292 options.PrefPortNumber.decorate($(id)); 293 }); 294 295 options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list')); 296 $('remove-host').addEventListener('click', 297 this.handleRemoveProxyExceptions_); 298 $('add-host').addEventListener('click', this.handleAddProxyException_); 299 $('direct-proxy').addEventListener('click', this.disableManualProxy_); 300 $('manual-proxy').addEventListener('click', this.enableManualProxy_); 301 $('auto-proxy').addEventListener('click', this.disableManualProxy_); 302 $('proxy-all-protocols').addEventListener('click', 303 this.toggleSingleProxy_); 304 $('proxy-use-pac-url').addEventListener('change', 305 this.handleAutoConfigProxy_); 306 307 observePrefsUI($('direct-proxy')); 308 observePrefsUI($('manual-proxy')); 309 observePrefsUI($('auto-proxy')); 310 observePrefsUI($('proxy-all-protocols')); 311 observePrefsUI($('proxy-use-pac-url')); 312 313 $('ip-automatic-configuration-checkbox').addEventListener('click', 314 this.handleIpAutoConfig_); 315 $('automatic-dns-radio').addEventListener('click', 316 this.handleNameServerTypeChange_); 317 $('google-dns-radio').addEventListener('click', 318 this.handleNameServerTypeChange_); 319 $('user-dns-radio').addEventListener('click', 320 this.handleNameServerTypeChange_); 321 322 // We only load this string if we have the string data available 323 // because the proxy settings page on the login screen re-uses the 324 // proxy sub-page from the internet options, and it doesn't ever 325 // show the DNS settings, so we don't need this string there. 326 // The string isn't available because 327 // chrome://settings-frame/strings.js (where the string is 328 // stored) is not accessible from the login screen. 329 // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login 330 // page is fixed. http://crbug.com/242865 331 if (loadTimeData.data_) { 332 $('google-dns-label').innerHTML = 333 loadTimeData.getString('googleNameServers'); 334 } 335 }, 336 337 /** 338 * Handler for "add" event fired from userNameEdit. 339 * @param {Event} e Add event fired from userNameEdit. 340 * @private 341 */ 342 handleAddProxyException_: function(e) { 343 var exception = $('new-host').value; 344 $('new-host').value = ''; 345 346 exception = exception.trim(); 347 if (exception) 348 $('ignored-host-list').addException(exception); 349 }, 350 351 /** 352 * Handler for when the remove button is clicked 353 * @param {Event} e The click event. 354 * @private 355 */ 356 handleRemoveProxyExceptions_: function(e) { 357 var selectedItems = $('ignored-host-list').selectedItems; 358 for (var x = 0; x < selectedItems.length; x++) { 359 $('ignored-host-list').removeException(selectedItems[x]); 360 } 361 }, 362 363 /** 364 * Handler for when the IP automatic configuration checkbox is clicked. 365 * @param {Event} e The click event. 366 * @private 367 */ 368 handleIpAutoConfig_: function(e) { 369 var checked = $('ip-automatic-configuration-checkbox').checked; 370 var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')]; 371 for (var i = 0; i < fields.length; ++i) { 372 fields[i].editable = !checked; 373 if (checked) { 374 var model = fields[i].model; 375 model.value = model.automatic; 376 fields[i].model = model; 377 } 378 } 379 if (!checked) 380 $('ip-address').focus(); 381 }, 382 383 /** 384 * Handler for when the name server selection changes. 385 * @param {Event} e The click event. 386 * @private 387 */ 388 handleNameServerTypeChange_: function(event) { 389 var type = event.target.value; 390 DetailsInternetPage.updateNameServerDisplay(type); 391 }, 392 393 /** 394 * Update details page controls. 395 * @private 396 */ 397 updateControls: function() { 398 // Only show ipconfig section if network is connected OR if nothing on 399 // this device is connected. This is so that you can fix the ip configs 400 // if you can't connect to any network. 401 // TODO(chocobo): Once ipconfig is moved to flimflam service objects, 402 // we need to redo this logic to allow configuration of all networks. 403 $('ipconfig-section').hidden = !this.connected && this.deviceConnected; 404 $('ipconfig-dns-section').hidden = 405 !this.connected && this.deviceConnected; 406 407 // Network type related. 408 updateHidden('#details-internet-page .cellular-details', !this.cellular); 409 updateHidden('#details-internet-page .wifi-details', !this.wireless); 410 updateHidden('#details-internet-page .wimax-details', !this.wimax); 411 updateHidden('#details-internet-page .vpn-details', !this.vpn); 412 updateHidden('#details-internet-page .proxy-details', !this.showProxy); 413 // Conditionally call updateHidden on .gsm-only, so that we don't unhide 414 // a previously hidden element. 415 if (this.gsm) 416 updateHidden('#details-internet-page .cdma-only', true); 417 else 418 updateHidden('#details-internet-page .gsm-only', true); 419 /* Network information merged into the Wifi tab for wireless networks 420 unless the option is set for enabling a static IP configuration. */ 421 updateHidden('#details-internet-page .network-details', 422 (this.wireless && !this.showStaticIPConfig) || this.vpn); 423 updateHidden('#details-internet-page .wifi-network-setting', 424 this.showStaticIPConfig); 425 426 // Wifi - Password and shared. 427 updateHidden('#details-internet-page #password-details', 428 !this.wireless || !this.password); 429 updateHidden('#details-internet-page #wifi-shared-network', 430 !this.shared); 431 updateHidden('#details-internet-page #prefer-network', 432 !this.showPreferred); 433 434 // WiMAX. 435 updateHidden('#details-internet-page #wimax-shared-network', 436 !this.shared); 437 438 // Proxy 439 this.updateProxyBannerVisibility_(); 440 this.toggleSingleProxy_(); 441 if ($('manual-proxy').checked) 442 this.enableManualProxy_(); 443 else 444 this.disableManualProxy_(); 445 }, 446 447 /** 448 * Updates info banner visibility state. This function shows the banner 449 * if proxy is managed or shared-proxies is off for shared network. 450 * @private 451 */ 452 updateProxyBannerVisibility_: function() { 453 var bannerDiv = $('network-proxy-info-banner'); 454 if (!loadTimeData.data_) { 455 // TODO(pneubeck): This temporarily prevents an exception below until 456 // i18n of the proxy dialog on the login page is 457 // fixed. http://crbug.com/242865 458 bannerDiv.hidden = true; 459 return; 460 } 461 462 // Show banner and determine its message if necessary. 463 var controlledBy = $('direct-proxy').controlledBy; 464 if (!controlledBy || controlledBy == '') { 465 bannerDiv.hidden = true; 466 } else { 467 bannerDiv.hidden = false; 468 // The possible banner texts are loaded in proxy_handler.cc. 469 var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() + 470 controlledBy.slice(1); 471 $('banner-text').textContent = loadTimeData.getString(bannerText); 472 } 473 }, 474 475 /** 476 * Handler for when the user clicks on the checkbox to allow a 477 * single proxy usage. 478 * @private 479 * @param {Event} e Click Event. 480 */ 481 toggleSingleProxy_: function(e) { 482 if ($('proxy-all-protocols').checked) { 483 $('multi-proxy').hidden = true; 484 $('single-proxy').hidden = false; 485 } else { 486 $('multi-proxy').hidden = false; 487 $('single-proxy').hidden = true; 488 } 489 }, 490 491 /** 492 * Handler for when the user clicks on the checkbox to enter 493 * auto configuration URL. 494 * @private 495 * @param {Event} e Click Event. 496 */ 497 handleAutoConfigProxy_: function(e) { 498 $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked; 499 }, 500 501 /** 502 * Handler for selecting a radio button that will disable the manual 503 * controls. 504 * @private 505 * @param {Event} e Click event. 506 */ 507 disableManualProxy_: function(e) { 508 $('ignored-host-list').disabled = true; 509 $('new-host').disabled = true; 510 $('remove-host').disabled = true; 511 $('add-host').disabled = true; 512 $('proxy-all-protocols').disabled = true; 513 $('proxy-host-name').disabled = true; 514 $('proxy-host-port').disabled = true; 515 $('proxy-host-single-name').disabled = true; 516 $('proxy-host-single-port').disabled = true; 517 $('secure-proxy-host-name').disabled = true; 518 $('secure-proxy-port').disabled = true; 519 $('ftp-proxy').disabled = true; 520 $('ftp-proxy-port').disabled = true; 521 $('socks-host').disabled = true; 522 $('socks-port').disabled = true; 523 $('proxy-use-pac-url').disabled = $('auto-proxy').disabled || 524 !$('auto-proxy').checked; 525 $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled || 526 !$('proxy-use-pac-url').checked; 527 $('auto-proxy-parms').hidden = !$('auto-proxy').checked; 528 $('manual-proxy-parms').hidden = !$('manual-proxy').checked; 529 }, 530 531 /** 532 * Handler for selecting a radio button that will enable the manual 533 * controls. 534 * @private 535 * @param {Event} e Click event. 536 */ 537 enableManualProxy_: function(e) { 538 $('ignored-host-list').redraw(); 539 var allDisabled = $('manual-proxy').disabled; 540 $('ignored-host-list').disabled = allDisabled; 541 $('new-host').disabled = allDisabled; 542 $('remove-host').disabled = allDisabled; 543 $('add-host').disabled = allDisabled; 544 $('proxy-all-protocols').disabled = allDisabled; 545 $('proxy-host-name').disabled = allDisabled; 546 $('proxy-host-port').disabled = allDisabled; 547 $('proxy-host-single-name').disabled = allDisabled; 548 $('proxy-host-single-port').disabled = allDisabled; 549 $('secure-proxy-host-name').disabled = allDisabled; 550 $('secure-proxy-port').disabled = allDisabled; 551 $('ftp-proxy').disabled = allDisabled; 552 $('ftp-proxy-port').disabled = allDisabled; 553 $('socks-host').disabled = allDisabled; 554 $('socks-port').disabled = allDisabled; 555 $('proxy-use-pac-url').disabled = true; 556 $('proxy-pac-url').disabled = true; 557 $('auto-proxy-parms').hidden = !$('auto-proxy').checked; 558 $('manual-proxy-parms').hidden = !$('manual-proxy').checked; 559 }, 560 }; 561 562 /** 563 * Enables or Disables all buttons that provide operations on the cellular 564 * network. 565 */ 566 DetailsInternetPage.changeCellularButtonsState = function(disable) { 567 var buttonsToDisableList = 568 new Array('details-internet-login', 569 'details-internet-disconnect', 570 'details-internet-configure', 571 'activate-details', 572 'buyplan-details', 573 'view-account-details'); 574 575 for (var i = 0; i < buttonsToDisableList.length; ++i) { 576 button = $(buttonsToDisableList[i]); 577 button.disabled = disable; 578 } 579 }; 580 581 /** 582 * Shows a spinner while the carrier is changed. 583 */ 584 DetailsInternetPage.showCarrierChangeSpinner = function(visible) { 585 $('switch-carrier-spinner').hidden = !visible; 586 // Disable any buttons that allow us to operate on cellular networks. 587 DetailsInternetPage.changeCellularButtonsState(visible); 588 }; 589 590 /** 591 * Changes the network carrier. 592 */ 593 DetailsInternetPage.handleCarrierChanged = function() { 594 var carrierSelector = $('select-carrier'); 595 var carrier = carrierSelector[carrierSelector.selectedIndex].textContent; 596 DetailsInternetPage.showCarrierChangeSpinner(true); 597 var data = $('connection-state').data; 598 chrome.send('setCarrier', [data.servicePath, carrier]); 599 }; 600 601 /** 602 * Performs minimal initialization of the InternetDetails dialog in 603 * preparation for showing proxy-setttings. 604 */ 605 DetailsInternetPage.initializeProxySettings = function() { 606 var detailsPage = DetailsInternetPage.getInstance(); 607 detailsPage.initializePageContents_(); 608 }; 609 610 /** 611 * Displays the InternetDetails dialog with only the proxy settings visible. 612 */ 613 DetailsInternetPage.showProxySettings = function() { 614 var detailsPage = DetailsInternetPage.getInstance(); 615 $('network-details-header').hidden = true; 616 $('buyplan-details').hidden = true; 617 $('activate-details').hidden = true; 618 $('view-account-details').hidden = true; 619 $('web-proxy-auto-discovery').hidden = true; 620 detailsPage.cellular = false; 621 detailsPage.wireless = false; 622 detailsPage.vpn = false; 623 detailsPage.showProxy = true; 624 updateHidden('#internet-tab', true); 625 updateHidden('#details-tab-strip', true); 626 updateHidden('#details-internet-page .action-area', true); 627 detailsPage.updateControls(); 628 detailsPage.visible = true; 629 }; 630 631 /** 632 * Initializes even handling for keyboard driven flow. 633 */ 634 DetailsInternetPage.initializeKeyboardFlow = function() { 635 keyboard.initializeKeyboardFlow(); 636 }; 637 638 DetailsInternetPage.updateProxySettings = function(type) { 639 var proxyHost = null, 640 proxyPort = null; 641 642 if (type == 'cros.session.proxy.singlehttp') { 643 proxyHost = 'proxy-host-single-name'; 644 proxyPort = 'proxy-host-single-port'; 645 }else if (type == 'cros.session.proxy.httpurl') { 646 proxyHost = 'proxy-host-name'; 647 proxyPort = 'proxy-host-port'; 648 }else if (type == 'cros.session.proxy.httpsurl') { 649 proxyHost = 'secure-proxy-host-name'; 650 proxyPort = 'secure-proxy-port'; 651 }else if (type == 'cros.session.proxy.ftpurl') { 652 proxyHost = 'ftp-proxy'; 653 proxyPort = 'ftp-proxy-port'; 654 }else if (type == 'cros.session.proxy.socks') { 655 proxyHost = 'socks-host'; 656 proxyPort = 'socks-port'; 657 }else { 658 return; 659 } 660 661 var hostValue = $(proxyHost).value; 662 if (hostValue.indexOf(':') !== -1) { 663 if (hostValue.match(/:/g).length == 1) { 664 hostValue = hostValue.split(':'); 665 $(proxyHost).value = hostValue[0]; 666 $(proxyPort).value = hostValue[1]; 667 } 668 } 669 }; 670 671 DetailsInternetPage.updateCarrier = function() { 672 DetailsInternetPage.showCarrierChangeSpinner(false); 673 }; 674 675 DetailsInternetPage.updateSecurityTab = function(requirePin) { 676 $('sim-card-lock-enabled').checked = requirePin; 677 $('change-pin').hidden = !requirePin; 678 }; 679 680 DetailsInternetPage.loginFromDetails = function() { 681 var data = $('connection-state').data; 682 var servicePath = data.servicePath; 683 chrome.send('networkCommand', [String(data.type), 684 servicePath, 685 'connect']); 686 OptionsPage.closeOverlay(); 687 }; 688 689 DetailsInternetPage.disconnectNetwork = function() { 690 var data = $('connection-state').data; 691 var servicePath = data.servicePath; 692 chrome.send('networkCommand', [String(data.type), 693 servicePath, 694 'disconnect']); 695 OptionsPage.closeOverlay(); 696 }; 697 698 DetailsInternetPage.configureNetwork = function() { 699 var data = $('connection-state').data; 700 var servicePath = data.servicePath; 701 chrome.send('networkCommand', [String(data.type), 702 servicePath, 703 'configure']); 704 OptionsPage.closeOverlay(); 705 }; 706 707 DetailsInternetPage.activateFromDetails = function() { 708 var data = $('connection-state').data; 709 var servicePath = data.servicePath; 710 if (data.type == Constants.TYPE_CELLULAR) { 711 chrome.send('networkCommand', [String(data.type), 712 servicePath, 713 'activate']); 714 } 715 OptionsPage.closeOverlay(); 716 }; 717 718 DetailsInternetPage.setDetails = function() { 719 var data = $('connection-state').data; 720 var servicePath = data.servicePath; 721 if (data.type == Constants.TYPE_WIFI) { 722 sendCheckedIfEnabled(servicePath, 'setPreferNetwork', 723 $('prefer-network-wifi')); 724 sendCheckedIfEnabled(servicePath, 'setAutoConnect', 725 $('auto-connect-network-wifi')); 726 } else if (data.type == Constants.TYPE_WIMAX) { 727 sendCheckedIfEnabled(servicePath, 'setAutoConnect', 728 $('auto-connect-network-wimax')); 729 } else if (data.type == Constants.TYPE_CELLULAR) { 730 sendCheckedIfEnabled(servicePath, 'setAutoConnect', 731 $('auto-connect-network-cellular')); 732 } else if (data.type == Constants.TYPE_VPN) { 733 chrome.send('setServerHostname', 734 [servicePath, 735 $('inet-server-hostname').value]); 736 sendCheckedIfEnabled(servicePath, 'setAutoConnect', 737 $('auto-connect-network-vpn')); 738 } 739 740 var nameServerTypes = ['automatic', 'google', 'user']; 741 var nameServerType = 'automatic'; 742 for (var i = 0; i < nameServerTypes.length; ++i) { 743 if ($(nameServerTypes[i] + '-dns-radio').checked) { 744 nameServerType = nameServerTypes[i]; 745 break; 746 } 747 } 748 749 // Skip any empty values. 750 var userNameServers = []; 751 for (var i = 1; i <= 4; ++i) { 752 var nameServerField = $('ipconfig-dns' + i); 753 if (nameServerField && nameServerField.model && 754 nameServerField.model.value) { 755 userNameServers.push(nameServerField.model.value); 756 } 757 } 758 759 userNameServers = userNameServers.join(','); 760 761 chrome.send('setIPConfig', 762 [servicePath, 763 Boolean($('ip-automatic-configuration-checkbox').checked), 764 $('ip-address').model.value || '', 765 $('ip-netmask').model.value || '', 766 $('ip-gateway').model.value || '', 767 nameServerType, 768 userNameServers]); 769 OptionsPage.closeOverlay(); 770 }; 771 772 DetailsInternetPage.updateNameServerDisplay = function(type) { 773 var editable = type == 'user'; 774 var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'), 775 $('ipconfig-dns3'), $('ipconfig-dns4')]; 776 for (var i = 0; i < fields.length; ++i) { 777 fields[i].editable = editable; 778 } 779 if (editable) 780 $('ipconfig-dns1').focus(); 781 782 var automaticDns = $('automatic-dns-display'); 783 var googleDns = $('google-dns-display'); 784 var userDns = $('user-dns-settings'); 785 switch (type) { 786 case 'automatic': 787 automaticDns.setAttribute('selected', ''); 788 googleDns.removeAttribute('selected'); 789 userDns.removeAttribute('selected'); 790 break; 791 case 'google': 792 automaticDns.removeAttribute('selected'); 793 googleDns.setAttribute('selected', ''); 794 userDns.removeAttribute('selected'); 795 break; 796 case 'user': 797 automaticDns.removeAttribute('selected'); 798 googleDns.removeAttribute('selected'); 799 userDns.setAttribute('selected', ''); 800 break; 801 } 802 }; 803 804 DetailsInternetPage.updateConnectionButtonVisibilty = function(data) { 805 $('details-internet-login').hidden = data.connected; 806 $('details-internet-login').disabled = data.disableConnectButton; 807 808 if (!data.connected && 809 ((data.type == Constants.TYPE_WIFI && data.encryption) || 810 data.type == Constants.TYPE_WIMAX || 811 data.type == Constants.TYPE_VPN)) { 812 $('details-internet-configure').hidden = false; 813 } else { 814 $('details-internet-configure').hidden = true; 815 } 816 817 if (data.type == Constants.TYPE_ETHERNET) 818 $('details-internet-disconnect').hidden = true; 819 else 820 $('details-internet-disconnect').hidden = !data.connected; 821 }; 822 823 DetailsInternetPage.updateConnectionData = function(update) { 824 var detailsPage = DetailsInternetPage.getInstance(); 825 if (!detailsPage.visible) 826 return; 827 828 var data = $('connection-state').data; 829 if (!data) 830 return; 831 832 if (update.servicePath != data.servicePath) 833 return; 834 835 // Update our cached data object. 836 updateDataObject(data, update); 837 838 detailsPage.deviceConnected = data.deviceConnected; 839 detailsPage.connecting = data.connecting; 840 detailsPage.connected = data.connected; 841 $('connection-state').textContent = data.connectionState; 842 843 this.updateConnectionButtonVisibilty(data); 844 845 if (data.type == Constants.TYPE_WIFI) { 846 $('wifi-connection-state').textContent = data.connectionState; 847 } else if (data.type == Constants.TYPE_WIMAX) { 848 $('wimax-connection-state').textContent = data.connectionState; 849 } else if (data.type == Constants.TYPE_CELLULAR) { 850 $('activation-state').textContent = data.activationState; 851 852 $('buyplan-details').hidden = !data.showBuyButton; 853 $('view-account-details').hidden = !data.showViewAccountButton; 854 855 $('activate-details').hidden = !data.showActivateButton; 856 if (data.showActivateButton) 857 $('details-internet-login').hidden = true; 858 } 859 860 $('connection-state').data = data; 861 }; 862 863 DetailsInternetPage.showDetailedInfo = function(data) { 864 var detailsPage = DetailsInternetPage.getInstance(); 865 866 // Populate header 867 $('network-details-title').textContent = data.networkName; 868 var statusKey = data.connected ? 'networkConnected' : 869 'networkNotConnected'; 870 $('network-details-subtitle-status').textContent = 871 loadTimeData.getString(statusKey); 872 var typeKey = null; 873 switch (data.type) { 874 case Constants.TYPE_ETHERNET: 875 typeKey = 'ethernetTitle'; 876 break; 877 case Constants.TYPE_WIFI: 878 typeKey = 'wifiTitle'; 879 break; 880 case Constants.TYPE_WIMAX: 881 typeKey = 'wimaxTitle'; 882 break; 883 case Constants.TYPE_CELLULAR: 884 typeKey = 'cellularTitle'; 885 break; 886 case Constants.TYPE_VPN: 887 typeKey = 'vpnTitle'; 888 break; 889 } 890 var typeLabel = $('network-details-subtitle-type'); 891 var typeSeparator = $('network-details-subtitle-separator'); 892 if (typeKey) { 893 typeLabel.textContent = loadTimeData.getString(typeKey); 894 typeLabel.hidden = false; 895 typeSeparator.hidden = false; 896 } else { 897 typeLabel.hidden = true; 898 typeSeparator.hidden = true; 899 } 900 901 // TODO(chocobo): Is this hack to cache the data here reasonable? 902 // TODO(kevers): Find more appropriate place to cache data. 903 $('connection-state').data = data; 904 905 $('buyplan-details').hidden = true; 906 $('activate-details').hidden = true; 907 $('view-account-details').hidden = true; 908 909 this.updateConnectionButtonVisibilty(data); 910 911 $('web-proxy-auto-discovery').hidden = true; 912 913 detailsPage.deviceConnected = data.deviceConnected; 914 detailsPage.connecting = data.connecting; 915 detailsPage.connected = data.connected; 916 detailsPage.showProxy = data.showProxy; 917 if (detailsPage.showProxy) 918 chrome.send('selectNetwork', [data.servicePath]); 919 920 detailsPage.showStaticIPConfig = data.showStaticIPConfig; 921 $('connection-state').textContent = data.connectionState; 922 923 var ipAutoConfig = data.ipAutoConfig ? 'automatic' : 'user'; 924 $('ip-automatic-configuration-checkbox').checked = data.ipAutoConfig; 925 var inetAddress = {autoConfig: ipAutoConfig}; 926 var inetNetmask = {autoConfig: ipAutoConfig}; 927 var inetGateway = {autoConfig: ipAutoConfig}; 928 929 if (data.ipconfig.value) { 930 inetAddress.automatic = data.ipconfig.value.address; 931 inetAddress.value = data.ipconfig.value.address; 932 inetNetmask.automatic = data.ipconfig.value.netmask; 933 inetNetmask.value = data.ipconfig.value.netmask; 934 inetGateway.automatic = data.ipconfig.value.gateway; 935 inetGateway.value = data.ipconfig.value.gateway; 936 if (data.ipconfig.value.webProxyAutoDiscoveryUrl) { 937 $('web-proxy-auto-discovery').hidden = false; 938 $('web-proxy-auto-discovery-url').value = 939 data.ipconfig.value.webProxyAutoDiscoveryUrl; 940 } 941 } 942 943 // Override the "automatic" values with the real saved DHCP values, 944 // if they are set. 945 if (data.savedIP.address) { 946 inetAddress.automatic = data.savedIP.address; 947 inetAddress.value = data.savedIP.address; 948 } 949 if (data.savedIP.netmask) { 950 inetNetmask.automatic = data.savedIP.netmask; 951 inetNetmask.value = data.savedIP.netmask; 952 } 953 if (data.savedIP.gateway) { 954 inetGateway.automatic = data.savedIP.gateway; 955 inetGateway.value = data.savedIP.gateway; 956 } 957 958 if (ipAutoConfig == 'user') { 959 if (data.staticIP.value.address) { 960 inetAddress.value = data.staticIP.value.address; 961 inetAddress.user = data.staticIP.value.address; 962 } 963 if (data.staticIP.value.netmask) { 964 inetNetmask.value = data.staticIP.value.netmask; 965 inetNetmask.user = data.staticIP.value.netmask; 966 } 967 if (data.staticIP.value.gateway) { 968 inetGateway.value = data.staticIP.value.gateway; 969 inetGateway.user = data.staticIP.value.gateway; 970 } 971 } 972 973 var configureAddressField = function(field, model) { 974 IPAddressField.decorate(field); 975 field.model = model; 976 field.editable = model.autoConfig == 'user'; 977 }; 978 979 configureAddressField($('ip-address'), inetAddress); 980 configureAddressField($('ip-netmask'), inetNetmask); 981 configureAddressField($('ip-gateway'), inetGateway); 982 983 var inetNameServers = ''; 984 if (data.ipconfig.value && data.ipconfig.value.nameServers) { 985 inetNameServers = data.ipconfig.value.nameServers; 986 $('automatic-dns-display').textContent = inetNameServers; 987 } 988 989 if (data.savedIP && data.savedIP.nameServers) 990 $('automatic-dns-display').textContent = data.savedIP.nameServers; 991 992 if (data.nameServersGoogle) 993 $('google-dns-display').textContent = data.nameServersGoogle; 994 995 var nameServersUser = []; 996 if (data.staticIP.value.nameServers) 997 nameServersUser = data.staticIP.value.nameServers.split(','); 998 999 var nameServerModels = []; 1000 for (var i = 0; i < 4; ++i) 1001 nameServerModels.push({value: nameServersUser[i] || ''}); 1002 1003 $(data.nameServerType + '-dns-radio').checked = true; 1004 configureAddressField($('ipconfig-dns1'), nameServerModels[0]); 1005 configureAddressField($('ipconfig-dns2'), nameServerModels[1]); 1006 configureAddressField($('ipconfig-dns3'), nameServerModels[2]); 1007 configureAddressField($('ipconfig-dns4'), nameServerModels[3]); 1008 1009 DetailsInternetPage.updateNameServerDisplay(data.nameServerType); 1010 1011 if (data.hardwareAddress) { 1012 $('hardware-address').textContent = data.hardwareAddress; 1013 $('hardware-address-row').style.display = 'table-row'; 1014 } else { 1015 // This is most likely a device without a hardware address. 1016 $('hardware-address-row').style.display = 'none'; 1017 } 1018 if (data.type == Constants.TYPE_WIFI) { 1019 OptionsPage.showTab($('wifi-network-nav-tab')); 1020 detailsPage.wireless = true; 1021 detailsPage.vpn = false; 1022 detailsPage.ethernet = false; 1023 detailsPage.cellular = false; 1024 detailsPage.gsm = false; 1025 detailsPage.wimax = false; 1026 detailsPage.shared = data.shared; 1027 $('wifi-connection-state').textContent = data.connectionState; 1028 $('wifi-ssid').textContent = data.ssid; 1029 if (data.bssid && data.bssid.length > 0) { 1030 $('wifi-bssid').textContent = data.bssid; 1031 $('wifi-bssid-entry').hidden = false; 1032 } else { 1033 $('wifi-bssid-entry').hidden = true; 1034 } 1035 $('wifi-ip-address').textContent = inetAddress.value; 1036 $('wifi-netmask').textContent = inetNetmask.value; 1037 $('wifi-gateway').textContent = inetGateway.value; 1038 $('wifi-name-servers').textContent = inetNameServers; 1039 if (data.encryption && data.encryption.length > 0) { 1040 $('wifi-security').textContent = data.encryption; 1041 $('wifi-security-entry').hidden = false; 1042 } else { 1043 $('wifi-security-entry').hidden = true; 1044 } 1045 // Frequency is in MHz. 1046 var frequency = loadTimeData.getString('inetFrequencyFormat'); 1047 frequency = frequency.replace('$1', data.frequency); 1048 $('wifi-frequency').textContent = frequency; 1049 // Signal strength as percentage. 1050 var signalStrength = loadTimeData.getString('inetSignalStrengthFormat'); 1051 signalStrength = signalStrength.replace('$1', data.strength); 1052 $('wifi-signal-strength').textContent = signalStrength; 1053 if (data.hardwareAddress) { 1054 $('wifi-hardware-address').textContent = data.hardwareAddress; 1055 $('wifi-hardware-address-entry').hidden = false; 1056 } else { 1057 $('wifi-hardware-address-entry').hidden = true; 1058 } 1059 detailsPage.showPreferred = data.showPreferred; 1060 $('prefer-network-wifi').checked = data.preferred.value; 1061 $('prefer-network-wifi').disabled = !data.remembered; 1062 $('auto-connect-network-wifi').checked = data.autoConnect.value; 1063 $('auto-connect-network-wifi').disabled = !data.remembered; 1064 detailsPage.password = data.encrypted; 1065 } else if (data.type == Constants.TYPE_WIMAX) { 1066 OptionsPage.showTab($('wimax-network-nav-tab')); 1067 detailsPage.wimax = true; 1068 detailsPage.wireless = false; 1069 detailsPage.vpn = false; 1070 detailsPage.ethernet = false; 1071 detailsPage.cellular = false; 1072 detailsPage.gsm = false; 1073 detailsPage.shared = data.shared; 1074 detailsPage.showPreferred = data.showPreferred; 1075 $('wimax-connection-state').textContent = data.connectionState; 1076 $('auto-connect-network-wimax').checked = data.autoConnect.value; 1077 $('auto-connect-network-wimax').disabled = !data.remembered; 1078 if (data.identity) { 1079 $('wimax-eap-identity').textContent = data.identity; 1080 $('wimax-eap-identity-entry').hidden = false; 1081 } else { 1082 $('wimax-eap-identity-entry').hidden = true; 1083 } 1084 // Signal strength as percentage. 1085 var signalStrength = loadTimeData.getString('inetSignalStrengthFormat'); 1086 signalStrength = signalStrength.replace('$1', data.strength); 1087 $('wimax-signal-strength').textContent = signalStrength; 1088 } else if (data.type == Constants.TYPE_CELLULAR) { 1089 OptionsPage.showTab($('cellular-conn-nav-tab')); 1090 detailsPage.ethernet = false; 1091 detailsPage.wireless = false; 1092 detailsPage.wimax = false; 1093 detailsPage.vpn = false; 1094 detailsPage.cellular = true; 1095 if (data.showCarrierSelect && data.currentCarrierIndex != -1) { 1096 var carrierSelector = $('select-carrier'); 1097 carrierSelector.onchange = DetailsInternetPage.handleCarrierChanged; 1098 carrierSelector.options.length = 0; 1099 for (var i = 0; i < data.carriers.length; ++i) { 1100 var option = document.createElement('option'); 1101 option.textContent = data.carriers[i]; 1102 carrierSelector.add(option); 1103 } 1104 carrierSelector.selectedIndex = data.currentCarrierIndex; 1105 } else { 1106 $('service-name').textContent = data.serviceName; 1107 } 1108 1109 $('network-technology').textContent = data.networkTechnology; 1110 $('activation-state').textContent = data.activationState; 1111 $('roaming-state').textContent = data.roamingState; 1112 $('restricted-pool').textContent = data.restrictedPool; 1113 $('error-state').textContent = data.errorState; 1114 $('manufacturer').textContent = data.manufacturer; 1115 $('model-id').textContent = data.modelId; 1116 $('firmware-revision').textContent = data.firmwareRevision; 1117 $('hardware-revision').textContent = data.hardwareRevision; 1118 $('mdn').textContent = data.mdn; 1119 $('operator-name').textContent = data.operatorName; 1120 $('operator-code').textContent = data.operatorCode; 1121 1122 // Make sure that GSM/CDMA specific properties that shouldn't be hidden 1123 // are visible. 1124 updateHidden('#details-internet-page .gsm-only', false); 1125 updateHidden('#details-internet-page .cdma-only', false); 1126 1127 // Show IMEI/ESN/MEID/MIN/PRL only if they are available. 1128 (function() { 1129 var setContentOrHide = function(property) { 1130 var value = data[property]; 1131 if (value) 1132 $(property).textContent = value; 1133 else 1134 $(property).parentElement.hidden = true; 1135 }; 1136 setContentOrHide('esn'); 1137 setContentOrHide('imei'); 1138 setContentOrHide('meid'); 1139 setContentOrHide('min'); 1140 setContentOrHide('prl-version'); 1141 })(); 1142 detailsPage.gsm = data.gsm; 1143 if (data.gsm) { 1144 $('iccid').textContent = stringFromValue(data.iccid); 1145 $('imsi').textContent = stringFromValue(data.imsi); 1146 1147 var apnSelector = $('select-apn'); 1148 // Clear APN lists, keep only last element that "other". 1149 while (apnSelector.length != 1) 1150 apnSelector.remove(0); 1151 var otherOption = apnSelector[0]; 1152 data.selectedApn = -1; 1153 data.userApnIndex = -1; 1154 var apnList = data.providerApnList.value; 1155 for (var i = 0; i < apnList.length; i++) { 1156 var option = document.createElement('option'); 1157 var localizedName = apnList[i].localizedName; 1158 var name = localizedName ? localizedName : apnList[i].name; 1159 var apn = apnList[i].apn; 1160 option.textContent = name ? (name + ' (' + apn + ')') : apn; 1161 option.value = i; 1162 // data.apn and data.lastGoodApn will always be defined, however 1163 // data.apn.apn and data.lastGoodApn.apn may not be. This is not a 1164 // problem, as apnList[i].apn will always be defined and the 1165 // comparisons below will work as expected. 1166 if ((data.apn.apn == apn && 1167 data.apn.username == apnList[i].username && 1168 data.apn.password == apnList[i].password) || 1169 (!data.apn.apn && 1170 data.lastGoodApn.apn == apn && 1171 data.lastGoodApn.username == apnList[i].username && 1172 data.lastGoodApn.password == apnList[i].password)) { 1173 data.selectedApn = i; 1174 } 1175 // Insert new option before "other" option. 1176 apnSelector.add(option, otherOption); 1177 } 1178 if (data.selectedApn == -1 && data.apn.apn) { 1179 var option = document.createElement('option'); 1180 option.textContent = data.apn.apn; 1181 option.value = -1; 1182 apnSelector.add(option, otherOption); 1183 data.selectedApn = apnSelector.length - 2; 1184 data.userApnIndex = data.selectedApn; 1185 } 1186 apnSelector.selectedIndex = data.selectedApn; 1187 updateHidden('.apn-list-view', false); 1188 updateHidden('.apn-details-view', true); 1189 DetailsInternetPage.updateSecurityTab(data.simCardLockEnabled.value); 1190 } 1191 $('auto-connect-network-cellular').checked = data.autoConnect.value; 1192 $('auto-connect-network-cellular').disabled = false; 1193 1194 $('buyplan-details').hidden = !data.showBuyButton; 1195 $('view-account-details').hidden = !data.showViewAccountButton; 1196 $('activate-details').hidden = !data.showActivateButton; 1197 if (data.showActivateButton) { 1198 $('details-internet-login').hidden = true; 1199 } 1200 } else if (data.type == Constants.TYPE_VPN) { 1201 OptionsPage.showTab($('vpn-nav-tab')); 1202 detailsPage.wireless = false; 1203 detailsPage.wimax = false; 1204 detailsPage.vpn = true; 1205 detailsPage.ethernet = false; 1206 detailsPage.cellular = false; 1207 detailsPage.gsm = false; 1208 $('inet-service-name').textContent = data.serviceName; 1209 $('inet-provider-type').textContent = data.providerType; 1210 $('inet-username').textContent = data.username; 1211 var inetServerHostname = $('inet-server-hostname'); 1212 inetServerHostname.value = data.serverHostname.value; 1213 inetServerHostname.resetHandler = function() { 1214 OptionsPage.hideBubble(); 1215 inetServerHostname.value = data.serverHostname.recommendedValue; 1216 }; 1217 $('auto-connect-network-vpn').checked = data.autoConnect.value; 1218 $('auto-connect-network-vpn').disabled = false; 1219 } else { 1220 OptionsPage.showTab($('internet-nav-tab')); 1221 detailsPage.ethernet = true; 1222 detailsPage.wireless = false; 1223 detailsPage.wimax = false; 1224 detailsPage.vpn = false; 1225 detailsPage.cellular = false; 1226 detailsPage.gsm = false; 1227 } 1228 1229 // Update controlled option indicators. 1230 indicators = cr.doc.querySelectorAll( 1231 '#details-internet-page .controlled-setting-indicator'); 1232 for (var i = 0; i < indicators.length; i++) { 1233 var propName = indicators[i].getAttribute('data'); 1234 if (!propName || !data[propName]) 1235 continue; 1236 var propData = data[propName]; 1237 // Create a synthetic pref change event decorated as 1238 // CoreOptionsHandler::CreateValueForPref() does. 1239 var event = new Event(name); 1240 event.value = { 1241 value: propData.value, 1242 controlledBy: propData.controlledBy, 1243 recommendedValue: propData.recommendedValue, 1244 }; 1245 indicators[i].handlePrefChange(event); 1246 var forElement = $(indicators[i].getAttribute('for')); 1247 if (forElement) { 1248 if (propData.controlledBy == 'policy') 1249 forElement.disabled = true; 1250 if (forElement.resetHandler) 1251 indicators[i].resetHandler = forElement.resetHandler; 1252 } 1253 } 1254 1255 detailsPage.updateControls(); 1256 1257 // Don't show page name in address bar and in history to prevent people 1258 // navigate here by hand and solve issue with page session restore. 1259 OptionsPage.showPageByName('detailsInternetPage', false); 1260 }; 1261 1262 return { 1263 DetailsInternetPage: DetailsInternetPage 1264 }; 1265 }); 1266