// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.exportPath('options');

/**
 * @typedef {{actionLinkText: (string|undefined),
 *            accountInfo: (string|undefined),
 *            childUser: (boolean|undefined),
 *            hasError: (boolean|undefined),
 *            hasUnrecoverableError: (boolean|undefined),
 *            managed: (boolean|undefined),
 *            setupCompleted: (boolean|undefined),
 *            setupInProgress: (boolean|undefined),
 *            signedIn: (boolean|undefined),
 *            signinAllowed: (boolean|undefined),
 *            signoutAllowed: (boolean|undefined),
 *            statusAction: (string|undefined),
 *            statusText: (string|undefined),
 *            supervisedUser: (boolean|undefined),
 *            syncSystemEnabled: (boolean|undefined)}}
 * @see chrome/browser/ui/webui/options/browser_options_handler.cc
 */
options.SyncStatus;

/**
 * @typedef {{id: string, name: string}}
 */
options.ExtensionData;

/**
 * @typedef {{name: string,
 *            filePath: string,
 *            isCurrentProfile: boolean,
 *            isSupervised: boolean,
 *            isChild: boolean,
 *            iconUrl: string}}
 * @see chrome/browser/ui/webui/options/browser_options_handler.cc
 */
options.Profile;

/**
 * Device policy SystemTimezoneAutomaticDetection values.
 * @enum {number}
 * @const
 */
options.AutomaticTimezoneDetectionType = {
  USERS_DECIDE: 0,
  DISABLED: 1,
  IP_ONLY: 2,
  SEND_WIFI_ACCESS_POINTS: 3,
};

cr.define('options', function() {
  var OptionsPage = options.OptionsPage;
  var Page = cr.ui.pageManager.Page;
  var PageManager = cr.ui.pageManager.PageManager;
  var ArrayDataModel = cr.ui.ArrayDataModel;
  var RepeatingButton = cr.ui.RepeatingButton;
  var HotwordSearchSettingIndicator = options.HotwordSearchSettingIndicator;
  var NetworkPredictionOptions = {
    ALWAYS: 0,
    WIFI_ONLY: 1,
    NEVER: 2,
    DEFAULT: 1
  };

  /**
   * Encapsulated handling of browser options page.
   * @constructor
   * @extends {cr.ui.pageManager.Page}
   */
  function BrowserOptions() {
    Page.call(this, 'settings', loadTimeData.getString('settingsTitle'),
              'settings');
  }

  cr.addSingletonGetter(BrowserOptions);

  /**
   * @param {HTMLElement} section The section to show or hide.
   * @return {boolean} Whether the section should be shown.
   * @private
   */
  BrowserOptions.shouldShowSection_ = function(section) {
    // If the section is hidden or hiding, it should be shown.
    return section.style.height == '' || section.style.height == '0px';
  };

  BrowserOptions.prototype = {
    __proto__: Page.prototype,

    /**
     * Keeps track of whether the user is signed in or not.
     * @private {boolean}
     */
    signedIn_: false,

    /**
     * Indicates whether signing out is allowed or whether a complete profile
     * wipe is required to remove the current enterprise account.
     * @private {boolean}
     */
    signoutAllowed_: true,

    /**
     * Keeps track of whether |onShowHomeButtonChanged_| has been called. See
     * |onShowHomeButtonChanged_|.
     * @private {boolean}
     */
    onShowHomeButtonChangedCalled_: false,

    /**
     * Track if page initialization is complete.  All C++ UI handlers have the
     * chance to manipulate page content within their InitializePage methods.
     * This flag is set to true after all initializers have been called.
     * @private {boolean}
     */
    initializationComplete_: false,

    /**
     * Current status of "Resolve Timezone by Geolocation" checkbox.
     * @private {boolean}
     */
    resolveTimezoneByGeolocation_: false,

    /**
     * True if system timezone is managed by policy.
     * @private {boolean}
     */
    systemTimezoneIsManaged_: false,

    /**
     * True if system timezone detection is managed by policy.
     * @private {boolean}
     */
    systemTimezoneAutomaticDetectionIsManaged_: false,

    /**
     * This is the value of SystemTimezoneAutomaticDetection policy.
     * @private {number}
     */
    systemTimezoneAutomaticDetectionValue_: 0,

    /**
     * Cached bluetooth adapter state.
     * @private {?chrome.bluetooth.AdapterState}
     */
    bluetoothAdapterState_: null,

    /** @override */
    initializePage: function() {
      Page.prototype.initializePage.call(this);
      var self = this;

      if (window.top != window) {
        // The options page is not in its own window.
        document.body.classList.add('uber-frame');
        PageManager.horizontalOffset = 155;
      }

      // Ensure that navigation events are unblocked on uber page. A reload of
      // the settings page while an overlay is open would otherwise leave uber
      // page in a blocked state, where tab switching is not possible.
      uber.invokeMethodOnParent('stopInterceptingEvents');

      window.addEventListener('message', this.handleWindowMessage_.bind(this));

      if (loadTimeData.getBoolean('allowAdvancedSettings')) {
        $('advanced-settings-expander').onclick = function(e) {
          var showAdvanced =
              BrowserOptions.shouldShowSection_($('advanced-settings'));
          if (showAdvanced) {
            chrome.send('coreOptionsUserMetricsAction',
                        ['Options_ShowAdvancedSettings']);
          }
          self.toggleSectionWithAnimation_(
              $('advanced-settings'),
              $('advanced-settings-container'));

          // If the click was triggered using the keyboard and it showed the
          // section (rather than hiding it), focus the first element in the
          // container.
          if (e.detail == 0 && showAdvanced) {
            var focusElement = $('advanced-settings-container').querySelector(
                'button, input, list, select, a[href]');
            if (focusElement)
              focusElement.focus();
          }
        };
      } else {
        $('advanced-settings-footer').hidden = true;
        $('advanced-settings').hidden = true;
      }

      $('advanced-settings').addEventListener('webkitTransitionEnd',
          this.updateAdvancedSettingsExpander_.bind(this));

      if (loadTimeData.getBoolean('showAbout')) {
        $('about-button').hidden = false;
        $('about-button').addEventListener('click', function() {
          PageManager.showPageByName('help');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_About']);
        });
      }

      if (cr.isChromeOS) {
        UIAccountTweaks.applyGuestSessionVisibility(document);
        UIAccountTweaks.applyPublicSessionVisibility(document);
        if (loadTimeData.getBoolean('secondaryUser'))
          $('secondary-user-banner').hidden = false;
      }

      // Sync (Sign in) section.
      this.updateSyncState_(/** @type {options.SyncStatus} */(
          loadTimeData.getValue('syncData')));
      if (!$('sync-overview').hidden) {
        chrome.send('metricsHandler:recordAction',
                    ['Signin_Impression_FromSettings']);
      }

      $('start-stop-sync').onclick = function(event) {
        if (self.signedIn_) {
          if (self.signoutAllowed_)
            SyncSetupOverlay.showStopSyncingUI();
          else
            chrome.send('showDisconnectManagedProfileDialog');
        } else if (cr.isChromeOS) {
          SyncSetupOverlay.showSetupUI();
        } else {
          SyncSetupOverlay.startSignIn(false /* creatingSupervisedUser */);
        }
      };
      $('customize-sync').onclick = function(event) {
        SyncSetupOverlay.showSetupUI();
      };

      // Internet connection section (ChromeOS only).
      if (cr.isChromeOS) {
        options.network.NetworkList.decorate($('network-list'));
        // Show that the network settings are shared if this is a secondary user
        // in a multi-profile session.
        if (loadTimeData.getBoolean('secondaryUser')) {
          var networkIndicator = document.querySelector(
              '#network-section-header > .controlled-setting-indicator');
          networkIndicator.setAttribute('controlled-by', 'shared');
          networkIndicator.location = cr.ui.ArrowLocation.TOP_START;
        }
      }

      // On Startup section.
      Preferences.getInstance().addEventListener('session.restore_on_startup',
          this.onRestoreOnStartupChanged_.bind(this));
      Preferences.getInstance().addEventListener(
          'session.startup_urls',
          function(event) {
            $('startup-set-pages').disabled = event.value.disabled;
          });

      $('startup-set-pages').onclick = function() {
        PageManager.showPageByName('startup');
      };

      // Appearance section.
      Preferences.getInstance().addEventListener('browser.show_home_button',
          this.onShowHomeButtonChanged_.bind(this));

      Preferences.getInstance().addEventListener('homepage',
          this.onHomePageChanged_.bind(this));
      Preferences.getInstance().addEventListener('homepage_is_newtabpage',
          this.onHomePageIsNtpChanged_.bind(this));

      $('change-home-page').onclick = function(event) {
        PageManager.showPageByName('homePageOverlay');
        chrome.send('coreOptionsUserMetricsAction',
                    ['Options_Homepage_ShowSettings']);
      };

      HotwordSearchSettingIndicator.decorate(
          $('hotword-search-setting-indicator'));
      HotwordSearchSettingIndicator.decorate(
          $('hotword-no-dsp-search-setting-indicator'));
      var hotwordIndicator = $('hotword-always-on-search-setting-indicator');
      HotwordSearchSettingIndicator.decorate(hotwordIndicator);
      hotwordIndicator.disabledOnErrorSection =
          $('hotword-always-on-search-checkbox');
      chrome.send('requestHotwordAvailable');

      chrome.send('requestGoogleNowAvailable');

      if ($('set-wallpaper')) {
        $('set-wallpaper').onclick = function(event) {
          chrome.send('openWallpaperManager');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_OpenWallpaperManager']);
        };
      }

      // Control the hotword-always-on pref with the Hotword Audio
      // Verification app.
      $('hotword-always-on-search-checkbox').customChangeHandler =
          function(event) {
        if (!$('hotword-always-on-search-checkbox').checked)
          return false;

        $('hotword-always-on-search-checkbox').checked = false;
        chrome.send('launchHotwordAudioVerificationApp', [false]);
        return true;
      };

      // Open the Hotword Audio Verification app to retrain a voice model.
      $('hotword-retrain-link').onclick = function(event) {
        chrome.send('launchHotwordAudioVerificationApp', [true]);
      };
      Preferences.getInstance().addEventListener(
          'hotword.always_on_search_enabled',
          this.onHotwordAlwaysOnChanged_.bind(this));

      $('themes-gallery').onclick = function(event) {
        window.open(loadTimeData.getString('themesGalleryURL'));
        chrome.send('coreOptionsUserMetricsAction',
                    ['Options_ThemesGallery']);
      };
      $('themes-reset').onclick = function(event) {
        chrome.send('themesReset');
      };

      if (loadTimeData.getBoolean('profileIsSupervised')) {
        if ($('themes-native-button')) {
          $('themes-native-button').disabled = true;
          $('themes-native-button').hidden = true;
        }
        // Supervised users have just one default theme, even on Linux. So use
        // the same button for Linux as for the other platforms.
        $('themes-reset').textContent = loadTimeData.getString('themesReset');
      }

      // Device section (ChromeOS only).
      if (cr.isChromeOS) {
        if (loadTimeData.getBoolean('showStylusSettings')) {
          $('stylus-settings-link').onclick = function(event) {
            PageManager.showPageByName('stylus-overlay');
          };
          $('stylus-row').hidden = false;
        }
        if (loadTimeData.getBoolean('showPowerStatus')) {
          $('power-settings-link').onclick = function(evt) {
            PageManager.showPageByName('power-overlay');
            chrome.send('coreOptionsUserMetricsAction',
                        ['Options_ShowPowerSettings']);
          };
          $('power-row').hidden = false;
        }
        $('keyboard-settings-button').onclick = function(evt) {
          PageManager.showPageByName('keyboard-overlay');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_ShowKeyboardSettings']);
        };
        $('pointer-settings-button').onclick = function(evt) {
          PageManager.showPageByName('pointer-overlay');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_ShowTouchpadSettings']);
        };
        $('storage-manager-button').onclick = function(evt) {
          PageManager.showPageByName('storage');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_ShowStorageManager']);
        };
      }

      // Search section.
      $('manage-default-search-engines').onclick = function(event) {
        PageManager.showPageByName('searchEngines');
        chrome.send('coreOptionsUserMetricsAction',
                    ['Options_ManageSearchEngines']);
      };
      $('default-search-engine').addEventListener('change',
          this.setDefaultSearchEngine_);

      // Users section.
      if (loadTimeData.valueExists('profilesInfo')) {
        $('profiles-section').hidden = false;
        this.maybeShowUserSection_();

        var profilesList = $('profiles-list');
        options.browser_options.ProfileList.decorate(profilesList);
        profilesList.autoExpands = true;

        // The profiles info data in |loadTimeData| might be stale.
        this.setProfilesInfo_(/** @type {!Array<!options.Profile>} */(
            loadTimeData.getValue('profilesInfo')));
        chrome.send('requestProfilesInfo');

        profilesList.addEventListener('change',
            this.setProfileViewButtonsStatus_);
        $('profiles-create').onclick = function(event) {
          chrome.send('metricsHandler:recordAction',
                      ['Options_ShowCreateProfileDlg']);
          ManageProfileOverlay.showCreateDialog();
        };
        $('profiles-manage').onclick = function(event) {
          chrome.send('metricsHandler:recordAction',
                      ['Options_ShowEditProfileDlg']);
          ManageProfileOverlay.showManageDialog();
        };
        $('profiles-delete').onclick = function(event) {
          var selectedProfile = self.getSelectedProfileItem_();
          if (selectedProfile) {
            chrome.send('metricsHandler:recordAction',
                        ['Options_ShowDeleteProfileDlg']);
            ManageProfileOverlay.showDeleteDialog(selectedProfile);
          }
        };
        if (loadTimeData.getBoolean('profileIsSupervised')) {
          $('profiles-create').disabled = true;
        }
        if (!loadTimeData.getBoolean('allowProfileDeletion')) {
          $('profiles-delete').disabled = true;
          $('profiles-list').canDeleteItems = false;
        }
      }

      if (cr.isChromeOS) {
        // Username (canonical email) of the currently logged in user or
        // |kGuestUser| if a guest session is active.
        this.username_ = loadTimeData.getString('username');

        this.updateAccountPicture_();

        $('account-picture').onclick = this.showImagerPickerOverlay_;
        $('change-picture-caption').onclick = this.showImagerPickerOverlay_;

        $('manage-accounts-button').onclick = function(event) {
          PageManager.showPageByName('accounts');
          chrome.send('coreOptionsUserMetricsAction',
              ['Options_ManageAccounts']);
        };

        if (loadTimeData.getBoolean('showQuickUnlockSettings')) {
          $('manage-screenlock').onclick = function(event) {
            PageManager.showPageByName('quickUnlockConfigureOverlay');
          };
          $('manage-screenlock').hidden = false;
        }
      } else {
        $('import-data').onclick = function(event) {
          ImportDataOverlay.show();
          chrome.send('coreOptionsUserMetricsAction', ['Import_ShowDlg']);
        };

        if ($('themes-native-button')) {
          $('themes-native-button').onclick = function(event) {
            chrome.send('themesSetNative');
          };
        }
      }

      // Date and time section (CrOS only).
      if (cr.isChromeOS) {
        if ($('set-time-button'))
          $('set-time-button').onclick = this.handleSetTime_.bind(this);

        // Timezone
        if (loadTimeData.getBoolean('enableTimeZoneTrackingOption')) {
          $('resolve-timezone-by-geolocation-selection').hidden = false;
          this.resolveTimezoneByGeolocation_ = loadTimeData.getBoolean(
              'resolveTimezoneByGeolocationInitialValue');
          this.updateTimezoneSectionState_();
          Preferences.getInstance().addEventListener(
              'settings.resolve_timezone_by_geolocation',
              this.onResolveTimezoneByGeolocationChanged_.bind(this));
        }
      }

      // Default browser section.
      if (!cr.isChromeOS) {
        if (!loadTimeData.getBoolean('showSetDefault')) {
          $('set-default-browser-section').hidden = true;
        }
        $('set-as-default-browser').onclick = function(event) {
          chrome.send('becomeDefaultBrowser');
        };
      }

      // Privacy section.
      $('privacyContentSettingsButton').onclick = function(event) {
        PageManager.showPageByName('content');
        OptionsPage.showTab($('cookies-nav-tab'));
        chrome.send('coreOptionsUserMetricsAction',
            ['Options_ContentSettings']);
      };
      $('privacyClearDataButton').onclick = function(event) {
        PageManager.showPageByName('clearBrowserData');
        chrome.send('coreOptionsUserMetricsAction', ['Options_ClearData']);
      };

      if ($('metrics-reporting-enabled')) {
        $('metrics-reporting-enabled').checked =
            loadTimeData.getBoolean('metricsReportingEnabledAtStart');

        // A browser restart is never needed to toggle metrics reporting,
        // and is only needed to toggle crash reporting when using Breakpad.
        // Crashpad, used on Mac, does not require a browser restart.
        var togglingMetricsRequiresRestart = !cr.isMac && !cr.isChromeOS;
        $('metrics-reporting-enabled').onclick = function(event) {
          chrome.send('metricsReportingCheckboxChanged',
              [Boolean(event.currentTarget.checked)]);
          if (cr.isChromeOS) {
            // 'metricsReportingEnabled' element is only present on Chrome
            // branded builds, and the 'metricsReportingCheckboxAction' message
            // is only handled on ChromeOS.
            chrome.send('metricsReportingCheckboxAction',
                [String(event.currentTarget.checked)]);
          }

          if (togglingMetricsRequiresRestart) {
            $('metrics-reporting-reset-restart').hidden =
                loadTimeData.getBoolean('metricsReportingEnabledAtStart') ==
                    $('metrics-reporting-enabled').checked;
          }

        };

        // Initialize restart button if needed.
        if (togglingMetricsRequiresRestart) {
          // The localized string has the | symbol on each side of the text that
          // needs to be made into a button to restart Chrome. We parse the text
          // and build the button from that.
          var restartTextFragments =
              loadTimeData.getString('metricsReportingResetRestart').split('|');
          // Assume structure is something like "starting text |link text|
          // ending text" where both starting text and ending text may or may
          // not be present, but the split should always be in three pieces.
          var restartElements =
              $('metrics-reporting-reset-restart').querySelectorAll('*');
          for (var i = 0; i < restartTextFragments.length; i++) {
            restartElements[i].textContent = restartTextFragments[i];
          }
          restartElements[1].onclick = function(event) {
            chrome.send('restartBrowser');
          };
        }
      }
      $('networkPredictionOptions').onchange = function(event) {
        var value = (event.target.checked ?
            NetworkPredictionOptions.WIFI_ONLY :
            NetworkPredictionOptions.NEVER);
        var metric = event.target.metric;
        Preferences.setIntegerPref(
            'net.network_prediction_options',
            value,
            true,
            metric);
      };
      if (loadTimeData.valueExists('showWakeOnWifi') &&
          loadTimeData.getBoolean('showWakeOnWifi')) {
        $('wake-on-wifi').hidden = false;
      }

      // Bluetooth (CrOS only).
      if (cr.isChromeOS) {
        // Request the intial bluetooth adapter state.
        var adapterStateChanged =
            this.onBluetoothAdapterStateChanged_.bind(this);
        chrome.bluetooth.getAdapterState(adapterStateChanged);

        // Set up observers.
        chrome.bluetooth.onAdapterStateChanged.addListener(adapterStateChanged);
        var deviceAddedOrChanged =
            this.onBluetoothDeviceAddedOrChanged_.bind(this);
        chrome.bluetooth.onDeviceAdded.addListener(deviceAddedOrChanged);
        chrome.bluetooth.onDeviceChanged.addListener(deviceAddedOrChanged);
        chrome.bluetooth.onDeviceRemoved.addListener(
            this.onBluetoothDeviceRemoved_.bind(this));

        chrome.bluetoothPrivate.onPairing.addListener(
            this.onBluetoothPrivatePairing_.bind(this));

        // Initialize UI.
        options.system.bluetooth.BluetoothDeviceList.decorate(
            $('bluetooth-paired-devices-list'));

        $('bluetooth-add-device').onclick =
            this.handleAddBluetoothDevice_.bind(this);

        $('enable-bluetooth').onchange = function(event) {
          var state = $('enable-bluetooth').checked;
          chrome.bluetoothPrivate.setAdapterState({powered: state}, function() {
            if (chrome.runtime.lastError) {
              console.error('Error enabling bluetooth:',
                            chrome.runtime.lastError.message);
            }
          });
        };

        $('bluetooth-reconnect-device').onclick = function(event) {
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_BluetoothConnectPairedDevice']);
          var device = $('bluetooth-paired-devices-list').selectedItem;
          BluetoothPairing.connect(device);
        };

        $('bluetooth-paired-devices-list').addEventListener('change',
            function() {
          var item = $('bluetooth-paired-devices-list').selectedItem;
          var disabled = !item || item.connected || !item.connectable;
          $('bluetooth-reconnect-device').disabled = disabled;
        });
      }

      // Passwords and Forms section.
      $('autofill-settings').onclick = function(event) {
        PageManager.showPageByName('autofill');
        chrome.send('coreOptionsUserMetricsAction',
            ['Options_ShowAutofillSettings']);
      };
      $('manage-passwords').onclick = function(event) {
        PageManager.showPageByName('passwords');
        OptionsPage.showTab($('passwords-nav-tab'));
        chrome.send('coreOptionsUserMetricsAction',
            ['Options_ShowPasswordManager']);
      };
      if (cr.isChromeOS && UIAccountTweaks.loggedInAsGuest()) {
        // Disable and turn off Autofill in guest mode.
        var autofillEnabled = $('autofill-enabled');
        autofillEnabled.disabled = true;
        autofillEnabled.checked = false;
        cr.dispatchSimpleEvent(autofillEnabled, 'change');
        $('autofill-settings').disabled = true;

        // Disable and turn off Password Manager in guest mode.
        var passwordManagerEnabled = $('password-manager-enabled');
        passwordManagerEnabled.disabled = true;
        passwordManagerEnabled.checked = false;
        cr.dispatchSimpleEvent(passwordManagerEnabled, 'change');
        $('manage-passwords').disabled = true;
      }

      if (cr.isMac) {
        $('mac-passwords-warning').hidden =
            !loadTimeData.getBoolean('multiple_profiles');
      }

      // Network section.
      if (!cr.isChromeOS) {
        $('proxiesConfigureButton').onclick = function(event) {
          chrome.send('showNetworkProxySettings');
        };
      }

      // Easy Unlock section.
      if (loadTimeData.getBoolean('easyUnlockAllowed')) {
        $('easy-unlock-section').hidden = false;
        $('easy-unlock-setup-button').onclick = function(event) {
          chrome.send('launchEasyUnlockSetup');
        };
        $('easy-unlock-turn-off-button').onclick = function(event) {
          PageManager.showPageByName('easyUnlockTurnOffOverlay');
        };
      }
      $('easy-unlock-enable-proximity-detection').hidden =
          !loadTimeData.getBoolean('easyUnlockProximityDetectionAllowed');

      // Web Content section.
      $('fontSettingsCustomizeFontsButton').onclick = function(event) {
        PageManager.showPageByName('fonts');
        chrome.send('coreOptionsUserMetricsAction',
                    ['Options_ShowFontSettings']);
      };
      $('defaultFontSize').onchange = function(event) {
        var value = event.target.options[event.target.selectedIndex].value;
        Preferences.setIntegerPref(
             'webkit.webprefs.default_fixed_font_size',
             value - OptionsPage.SIZE_DIFFERENCE_FIXED_STANDARD, true);
        chrome.send('defaultFontSizeAction', [String(value)]);
      };
      $('defaultZoomFactor').onchange = function(event) {
        chrome.send('defaultZoomFactorAction',
            [String(event.target.options[event.target.selectedIndex].value)]);
      };
      $('safeBrowsingExtendedReportingCheckbox').onchange = function(event) {
        chrome.send('safeBrowsingExtendedReportingAction',
            [event.target.checked]);
      };

      // Languages section.
      var showLanguageOptions = function(event) {
        PageManager.showPageByName('languages');
        chrome.send('coreOptionsUserMetricsAction',
            ['Options_LanuageAndSpellCheckSettings']);
      };
      $('language-button').onclick = showLanguageOptions;
      $('manage-languages').onclick = showLanguageOptions;

      // Downloads section.
      Preferences.getInstance().addEventListener('download.default_directory',
          this.onDefaultDownloadDirectoryChanged_.bind(this));
      $('downloadLocationChangeButton').onclick = function(event) {
        chrome.send('selectDownloadLocation');
      };
      if (cr.isChromeOS) {
        $('disable-drive-row').hidden =
            UIAccountTweaks.loggedInAsSupervisedUser();
      }
      $('autoOpenFileTypesResetToDefault').onclick = function(event) {
        chrome.send('autoOpenFileTypesAction');
      };

      // HTTPS/SSL section.
      if (cr.isWindows || cr.isMac) {
        $('certificatesManageButton').onclick = function(event) {
          chrome.send('showManageSSLCertificates');
        };
      } else {
        $('certificatesManageButton').onclick = function(event) {
          PageManager.showPageByName('certificates');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_ManageSSLCertificates']);
        };
      }

      // CUPS Print section (CrOS only).
      if (cr.isChromeOS) {
        if (loadTimeData.getBoolean('cupsPrintEnabled')) {
          $('cups-printers-section').hidden = false;
          $('cupsPrintersManageButton').onclick = function() {
            chrome.send('showCupsPrintDevicesPage');
          };
        }
      }

      if (loadTimeData.getBoolean('cloudPrintShowMDnsOptions')) {
        $('cloudprint-options-mdns').hidden = false;
        $('cloudPrintDevicesPageButton').onclick = function() {
          chrome.send('showCloudPrintDevicesPage');
        };
      }

      // Accessibility section (CrOS only).
      if (cr.isChromeOS) {
        var updateAccessibilitySettingsSection = function() {
          $('accessibility-settings').hidden =
              !($('accessibility-spoken-feedback-check').checked);
        };
        Preferences.getInstance().addEventListener(
            'settings.accessibility',
            updateAccessibilitySettingsSection);
        $('accessibility-learn-more').onclick = function(unused_event) {
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_AccessibilityLearnMore']);
        };
        $('accessibility-settings-button').onclick = function(unused_event) {
          window.open(loadTimeData.getString('accessibilitySettingsURL'));
        };
        $('talkback-settings-button').onclick = function(unused_event) {
          chrome.send('showAccessibilityTalkBackSettings');
        };
        $('accessibility-spoken-feedback-check').onchange =
            updateAccessibilitySettingsSection;
        updateAccessibilitySettingsSection();

        var updateScreenMagnifierCenterFocus = function() {
          $('accessibility-screen-magnifier-center-focus-check').disabled =
              !$('accessibility-screen-magnifier-check').checked;
        };
        Preferences.getInstance().addEventListener(
            $('accessibility-screen-magnifier-check').getAttribute('pref'),
            updateScreenMagnifierCenterFocus);

        var updateDelayDropdown = function() {
          $('accessibility-autoclick-dropdown').disabled =
              !$('accessibility-autoclick-check').checked;
        };
        Preferences.getInstance().addEventListener(
            $('accessibility-autoclick-check').getAttribute('pref'),
            updateDelayDropdown);
        $('experimental-accessibility-features').hidden =
            !loadTimeData.getBoolean('enableExperimentalAccessibilityFeatures');
      }

      // Display management section (CrOS only).
      if (cr.isChromeOS) {
        $('display-options').onclick = function(event) {
          PageManager.showPageByName('display');
          chrome.send('coreOptionsUserMetricsAction',
                      ['Options_Display']);
        };
      }

      // Factory reset section (CrOS only).
      if (cr.isChromeOS) {
        $('factory-reset-restart').onclick = function(event) {
          PageManager.showPageByName('factoryResetData');
          chrome.send('onPowerwashDialogShow');
        };
      }

      // System section.
      if (!cr.isChromeOS) {
        var updateGpuRestartButton = function() {
          $('gpu-mode-reset-restart').hidden =
              loadTimeData.getBoolean('gpuEnabledAtStart') ==
              $('gpu-mode-checkbox').checked;
        };
        Preferences.getInstance().addEventListener(
            $('gpu-mode-checkbox').getAttribute('pref'),
            updateGpuRestartButton);
        $('gpu-mode-reset-restart-button').onclick = function(event) {
          chrome.send('restartBrowser');
        };
        updateGpuRestartButton();
      }

      // Reset profile settings section.
      $('reset-profile-settings').onclick = function(event) {
        // We use the hash to indicate the source of the reset request. The hash
        // is removed by the reset profile settings overlay once it has been
        // consumed.
        PageManager.showPageByName('resetProfileSettings', true,
                                   {hash: '#userclick'});
      };

      // Extension controlled UI.
      this.addExtensionControlledBox_('search-section-content',
                                      'search-engine-controlled',
                                      true);
      this.addExtensionControlledBox_('extension-controlled-container',
                                      'homepage-controlled',
                                      true);
      this.addExtensionControlledBox_('startup-section-content',
                                      'startpage-controlled',
                                      false);
      this.addExtensionControlledBox_('newtab-section-content',
                                      'newtab-controlled',
                                      false);
      this.addExtensionControlledBox_('proxy-section-content',
                                      'proxy-controlled',
                                      true);

      document.body.addEventListener('click', function(e) {
        var target = assertInstanceof(e.target, Node);
        var button = findAncestor(target, function(el) {
          return el.tagName == 'BUTTON' &&
                 el.dataset.extensionId !== undefined &&
                 el.dataset.extensionId.length;
        });
        if (button)
          chrome.send('disableExtension', [button.dataset.extensionId]);
      });

      // Setup ARC section.
      if (cr.isChromeOS) {
        $('android-apps-settings-label').innerHTML =
            loadTimeData.getString('androidAppsSettingsLabel');
        Preferences.getInstance().addEventListener('arc.enabled', function(e) {
          // Only change settings visibility on committed settings changes.
          if (e.value.uncommitted)
            return;

          var isArcEnabled = !e.value.value;
          var androidAppSettings = $('android-apps-settings');
          if (androidAppSettings != null)
            androidAppSettings.hidden = isArcEnabled;

          var talkbackSettingsButton = $('talkback-settings-button');
          if (talkbackSettingsButton != null)
            talkbackSettingsButton.hidden = isArcEnabled;
        });

        $('android-apps-settings-link').addEventListener('click', function(e) {
            // MouseEvent.detail indicates the current click count (or tap
            // count, in the case of touch events) in the 'click' event.
            var activatedFromKeyboard = e.detail == 0;
            chrome.send('showAndroidAppsSettings', [activatedFromKeyboard]);
        });
      }
    },

    /** @override */
    didShowPage: function() {
      $('search-field').focus();
    },

   /**
    * Called after all C++ UI handlers have called InitializePage to notify
    * that initialization is complete.
    * @private
    */
    notifyInitializationComplete_: function() {
      this.initializationComplete_ = true;
      cr.dispatchSimpleEvent(document, 'initializationComplete');
    },

    /**
     * Event listener for the 'session.restore_on_startup' pref.
     * @param {Event} event The preference change event.
     * @private
     */
    onRestoreOnStartupChanged_: function(event) {
      /** @const */ var showHomePageValue = 0;

      if (event.value.value == showHomePageValue) {
        // If the user previously selected "Show the homepage", the
        // preference will already be migrated to "Open a specific page". So
        // the only way to reach this code is if the 'restore on startup'
        // preference is managed.
        assert(event.value.controlledBy);

        // Select "open the following pages" and lock down the list of URLs
        // to reflect the intention of the policy.
        $('startup-show-pages').checked = true;
        StartupOverlay.getInstance().setControlsDisabled(true);
      } else {
        // Re-enable the controls in the startup overlay if necessary.
        StartupOverlay.getInstance().updateControlStates();
      }
    },

    /**
     * Handler for messages sent from the main uber page.
     * @param {Event} e The 'message' event from the uber page.
     * @private
     */
    handleWindowMessage_: function(e) {
      if ((/** @type {{method: string}} */(e.data)).method == 'frameSelected')
        $('search-field').focus();
    },

    /**
     * Animatedly changes height |from| a px number |to| a px number.
     * @param {HTMLElement} section The section to animate.
     * @param {HTMLElement} container The container of |section|.
     * @param {boolean} showing Whether to go from 0 -> container height or
     *     container height -> 0.
     * @private
     */
    animatedSectionHeightChange_: function(section, container, showing) {
      // If the section is already animating, dispatch a synthetic transition
      // end event as the upcoming code will cancel the current one.
      if (section.classList.contains('sliding'))
        cr.dispatchSimpleEvent(section, 'webkitTransitionEnd');

      this.addTransitionEndListener_(section);

      section.hidden = false;
      section.style.height = (showing ? 0 : container.offsetHeight) + 'px';
      section.classList.add('sliding');

      // Force a style recalc before starting the animation.
      /** @suppress {suspiciousCode} */
      section.offsetHeight;

      section.style.height = (showing ? container.offsetHeight : 0) + 'px';
    },

    /**
     * Shows the given section.
     * @param {HTMLElement} section The section to be shown.
     * @param {HTMLElement} container The container for the section. Must be
     *     inside of |section|.
     * @param {boolean} animate Indicate if the expansion should be animated.
     * @private
     */
    showSection_: function(section, container, animate) {
      if (section == $('advanced-settings') &&
          !loadTimeData.getBoolean('allowAdvancedSettings')) {
        return;
      }
      // Delay starting the transition if animating so that hidden change will
      // be processed.
      if (animate) {
        this.animatedSectionHeightChange_(section, container, true);
      } else {
        section.hidden = false;
        section.style.height = 'auto';
      }
    },

    /**
     * Shows the given section, with animation.
     * @param {HTMLElement} section The section to be shown.
     * @param {HTMLElement} container The container for the section. Must be
     *     inside of |section|.
     * @private
     */
    showSectionWithAnimation_: function(section, container) {
      this.showSection_(section, container, /* animate */ true);
    },

    /**
     * Hides the given |section| with animation.
     * @param {HTMLElement} section The section to be hidden.
     * @param {HTMLElement} container The container for the section. Must be
     *     inside of |section|.
     * @private
     */
    hideSectionWithAnimation_: function(section, container) {
      this.animatedSectionHeightChange_(section, container, false);
    },

    /**
     * Toggles the visibility of |section| in an animated way.
     * @param {HTMLElement} section The section to be toggled.
     * @param {HTMLElement} container The container for the section. Must be
     *     inside of |section|.
     * @private
     */
    toggleSectionWithAnimation_: function(section, container) {
      if (BrowserOptions.shouldShowSection_(section))
        this.showSectionWithAnimation_(section, container);
      else
        this.hideSectionWithAnimation_(section, container);
    },

    /**
     * Scrolls the settings page to make the section visible auto-expanding
     * advanced settings if required.  The transition is not animated.  This
     * method is used to ensure that a section associated with an overlay
     * is visible when the overlay is closed.
     * @param {!Element} section  The section to make visible.
     * @private
     */
    scrollToSection_: function(section) {
      var advancedSettings = $('advanced-settings');
      var container = $('advanced-settings-container');
      var expander = $('advanced-settings-expander');
      if (!expander.hidden &&
          advancedSettings.hidden &&
          section.parentNode == container) {
        this.showSection_($('advanced-settings'),
                          $('advanced-settings-container'),
                          /* animate */ false);
        this.updateAdvancedSettingsExpander_();
      }

      if (!this.initializationComplete_) {
        var self = this;
        var callback = function() {
           document.removeEventListener('initializationComplete', callback);
           self.scrollToSection_(section);
        };
        document.addEventListener('initializationComplete', callback);
        return;
      }

      var pageContainer = $('page-container');
      // pageContainer.offsetTop is relative to the screen.
      var pageTop = pageContainer.offsetTop;
      var sectionBottom = section.offsetTop + section.offsetHeight;
      // section.offsetTop is relative to the 'page-container'.
      var sectionTop = section.offsetTop;
      if (pageTop + sectionBottom > document.body.scrollHeight ||
          pageTop + sectionTop < 0) {
        // Currently not all layout updates are guaranteed to precede the
        // initializationComplete event (for example 'set-as-default-browser'
        // button) leaving some uncertainty in the optimal scroll position.
        // The section is placed approximately in the middle of the screen.
        var top = Math.min(0, document.body.scrollHeight / 2 - sectionBottom);
        pageContainer.style.top = top + 'px';
        pageContainer.oldScrollTop = -top;
      }
    },

    /**
     * Adds a |webkitTransitionEnd| listener to the given section so that
     * it can be animated. The listener will only be added to a given section
     * once, so this can be called as multiple times.
     * @param {HTMLElement} section The section to be animated.
     * @private
     */
    addTransitionEndListener_: function(section) {
      if (section.hasTransitionEndListener_)
        return;

      section.addEventListener('webkitTransitionEnd',
          this.onTransitionEnd_.bind(this));
      section.hasTransitionEndListener_ = true;
    },

    /**
     * Called after an animation transition has ended.
     * @param {Event} event The webkitTransitionEnd event. NOTE: May be
     *     synthetic.
     * @private
     */
    onTransitionEnd_: function(event) {
      if (event.propertyName && event.propertyName != 'height') {
        // If not a synthetic event or a real transition we care about, bail.
        return;
      }

      var section = event.target;
      section.classList.remove('sliding');

      if (!event.propertyName) {
        // Only real transitions past this point.
        return;
      }

      if (section.style.height == '0px') {
        // Hide the content so it can't get tab focus.
        section.hidden = true;
        section.style.height = '';
      } else {
        // Set the section height to 'auto' to allow for size changes
        // (due to font change or dynamic content).
        section.style.height = 'auto';
      }
    },

    /** @private */
    updateAdvancedSettingsExpander_: function() {
      var expander = $('advanced-settings-expander');
      if (BrowserOptions.shouldShowSection_($('advanced-settings')))
        expander.textContent = loadTimeData.getString('showAdvancedSettings');
      else
        expander.textContent = loadTimeData.getString('hideAdvancedSettings');
    },

    /**
     * Updates the sync section with the given state.
     * @param {options.SyncStatus} syncData A bunch of data records that
     *     describe the status of the sync system.
     * @private
     */
    updateSyncState_: function(syncData) {
      if (!syncData.signinAllowed &&
          (!syncData.supervisedUser || !cr.isChromeOS)) {
        $('sync-section').hidden = true;
        this.maybeShowUserSection_();
        return;
      }

      $('sync-section').hidden = false;
      this.maybeShowUserSection_();

      if (cr.isChromeOS && syncData.supervisedUser && !syncData.childUser) {
        var subSection = $('sync-section').firstChild;
        while (subSection) {
          if (subSection.nodeType == Node.ELEMENT_NODE)
            subSection.hidden = true;
          subSection = subSection.nextSibling;
        }

        $('account-picture-wrapper').hidden = false;
        $('sync-general').hidden = false;
        $('sync-status').hidden = true;

        return;
      }

      // If the user gets signed out while the advanced sync settings dialog is
      // visible, say, due to a dashboard clear, close the dialog.
      // However, if the user gets signed out as a result of abandoning first
      // time sync setup, do not call closeOverlay as it will redirect the
      // browser to the main settings page and override any in-progress
      // user-initiated navigation. See crbug.com/278030.
      // Note: SyncSetupOverlay.closeOverlay is a no-op if the overlay is
      // already hidden.
      if (this.signedIn_ && !syncData.signedIn && !syncData.setupInProgress)
        SyncSetupOverlay.closeOverlay();

      this.signedIn_ = !!syncData.signedIn;

      // Display the "advanced settings" button if we're signed in and sync is
      // not managed/disabled. If the user is signed in, but sync is disabled,
      // this button is used to re-enable sync.
      var customizeSyncButton = $('customize-sync');
      customizeSyncButton.hidden = !this.signedIn_ ||
                                   syncData.managed ||
                                   !syncData.syncSystemEnabled;

      // Only modify the customize button's text if the new text is different.
      // Otherwise, it can affect search-highlighting in the settings page.
      // See http://crbug.com/268265.
      var customizeSyncButtonNewText = syncData.setupCompleted ?
          loadTimeData.getString('customizeSync') :
          loadTimeData.getString('syncButtonTextStart');
      if (customizeSyncButton.textContent != customizeSyncButtonNewText)
        customizeSyncButton.textContent = customizeSyncButtonNewText;

      // Disable the "sign in" button if we're currently signing in, or if we're
      // already signed in and signout is not allowed.
      var signInButton = $('start-stop-sync');
      signInButton.disabled = syncData.setupInProgress;
      this.signoutAllowed_ = !!syncData.signoutAllowed;
      if (!syncData.signoutAllowed)
        $('start-stop-sync-indicator').setAttribute('controlled-by', 'policy');
      else
        $('start-stop-sync-indicator').removeAttribute('controlled-by');

      // Hide the "sign in" button on Chrome OS, and show it on desktop Chrome
      // (except for supervised users, which can't change their signed-in
      // status).
      signInButton.hidden = cr.isChromeOS || syncData.supervisedUser;

      signInButton.textContent =
          this.signedIn_ ?
              loadTimeData.getString('syncButtonTextStop') :
              syncData.setupInProgress ?
                  loadTimeData.getString('syncButtonTextInProgress') :
                  loadTimeData.getString('syncButtonTextSignIn');
      $('start-stop-sync-indicator').hidden = signInButton.hidden;

      $('account-info').textContent = syncData.accountInfo;
      $('account-info').hidden = !this.signedIn_;

      // TODO(estade): can this just be textContent?
      $('sync-status-text').innerHTML = syncData.statusText;
      var statusSet = syncData.statusText.length != 0;
      $('sync-overview').hidden =
          statusSet ||
          (cr.isChromeOS && UIAccountTweaks.loggedInAsPublicAccount());
      $('sync-status').hidden = !statusSet;

      $('sync-action-link').textContent = syncData.actionLinkText;
      // Don't show the action link if it is empty or undefined.
      $('sync-action-link').hidden = syncData.actionLinkText.length == 0;
      $('sync-action-link').disabled = syncData.managed ||
                                       !syncData.syncSystemEnabled;

      $('sync-action-link').onclick = function(event) {
        switch (syncData.statusAction) {
          case 'reauthenticate':
<if expr="chromeos">
            // On Chrome OS, sign out the user and sign in again to get fresh
            // credentials on auth errors.
            SyncSetupOverlay.doSignOutOnAuthError();
</if>
<if expr="not chromeos">
            if (syncData.signoutAllowed) {
              // Silently sign the user out without deleting their profile and
              // prompt them to sign back in.
              chrome.send('SyncSetupStopSyncing', [false /* deleteProfile */]);
              SyncSetupOverlay.startSignIn(false /* creatingSupervisedUser */);
            } else {
              chrome.send('showDisconnectManagedProfileDialog');
            }
</if>
            break;
          case 'upgradeClient':
            PageManager.showPageByName('help');
            break;
          default:
            SyncSetupOverlay.showSetupUI();
        }
      };

      if (syncData.hasError)
        $('sync-status').classList.add('sync-error');
      else
        $('sync-status').classList.remove('sync-error');

      // Disable the "customize / set up sync" button if sync has an
      // unrecoverable error. Also disable the button if sync has not been set
      // up and the user is being presented with a link to re-auth.
      // See crbug.com/289791.
      customizeSyncButton.disabled =
          syncData.hasUnrecoverableError ||
          (!syncData.setupCompleted && !$('sync-action-link').hidden);
    },

    /**
     * Update the UI depending on whether Easy Unlock is enabled for the current
     * profile.
     * @param {boolean} isEnabled True if the feature is enabled for the current
     *     profile.
     */
    updateEasyUnlock_: function(isEnabled) {
      $('easy-unlock-disabled').hidden = isEnabled;
      $('easy-unlock-enabled').hidden = !isEnabled;
      if (!isEnabled && EasyUnlockTurnOffOverlay.getInstance().visible) {
        EasyUnlockTurnOffOverlay.dismiss();
      }
    },

    /**
     * Update the UI depending on whether the current profile manages any
     * supervised users.
     * @param {boolean} show True if the current profile manages any supervised
     *     users.
     */
    updateManagesSupervisedUsers_: function(show) {
      $('profiles-supervised-dashboard-tip').hidden = !show;
      this.maybeShowUserSection_();
    },

    /**
     * Get the start/stop sync button DOM element. Used for testing.
     * @return {Element} The start/stop sync button.
     * @private
     */
    getStartStopSyncButton_: function() {
      return $('start-stop-sync');
    },

    /**
     * Event listener for the 'show home button' preference. Shows/hides the
     * UI for changing the home page with animation, unless this is the first
     * time this function is called, in which case there is no animation.
     * @param {Event} event The preference change event.
     */
    onShowHomeButtonChanged_: function(event) {
      var section = $('change-home-page-section');
      if (this.onShowHomeButtonChangedCalled_) {
        var container = $('change-home-page-section-container');
        if (event.value.value)
          this.showSectionWithAnimation_(section, container);
        else
          this.hideSectionWithAnimation_(section, container);
      } else {
        section.hidden = !event.value.value;
        this.onShowHomeButtonChangedCalled_ = true;
      }
    },

    /**
     * Activates the Hotword section from the System settings page.
     * @param {string} sectionId The id of the section to display.
     * @param {string} indicatorId The id of the indicator to display.
     * @param {string=} opt_error The error message to display.
     * @private
     */
    showHotwordCheckboxAndIndicator_: function(sectionId, indicatorId,
                                               opt_error) {
      $(sectionId).hidden = false;
      $(indicatorId).setError(opt_error);
      if (opt_error)
        $(indicatorId).updateBasedOnError();
    },

    /**
     * Activates the Hotword section from the System settings page.
     * @param {string=} opt_error The error message to display.
     * @private
     */
    showHotwordSection_: function(opt_error) {
      this.showHotwordCheckboxAndIndicator_(
          'hotword-search',
          'hotword-search-setting-indicator',
          opt_error);
    },

    /**
     * Activates the Always-On Hotword sections from the
     * System settings page.
     * @param {string=} opt_error The error message to display.
     * @private
     */
    showHotwordAlwaysOnSection_: function(opt_error) {
      this.showHotwordCheckboxAndIndicator_(
          'hotword-always-on-search',
          'hotword-always-on-search-setting-indicator',
          opt_error);
    },

    /**
     * Activates the Hotword section on devices with no DSP
     * from the System settings page.
     * @param {string=} opt_error The error message to display.
     * @private
     */
    showHotwordNoDspSection_: function(opt_error) {
      this.showHotwordCheckboxAndIndicator_(
          'hotword-no-dsp-search',
          'hotword-no-dsp-search-setting-indicator',
          opt_error);
    },

    /**
     * Controls the visibility of all the hotword sections.
     * @param {boolean} visible Whether to show hotword sections.
     * @private
     */
    setAllHotwordSectionsVisible_: function(visible) {
      $('hotword-search').hidden = !visible;
      $('hotword-always-on-search').hidden = !visible;
      $('hotword-no-dsp-search').hidden = !visible;
      $('audio-history').hidden = !visible;
    },

    /**
     * Shows or hides the hotword retrain link
     * @param {boolean} visible Whether to show the link.
     * @private
     */
    setHotwordRetrainLinkVisible_: function(visible) {
      $('hotword-retrain-link').hidden = !visible;
    },

    /**
     * Event listener for the 'hotword always on search enabled' preference.
     * Updates the visibility of the 'retrain' link.
     * @param {Event} event The preference change event.
     * @private
     */
    onHotwordAlwaysOnChanged_: function(event) {
      this.setHotwordRetrainLinkVisible_(event.value.value);
    },

    /**
     * Controls the visibility of the Now settings.
     * @param {boolean} visible Whether to show Now settings.
     * @private
     */
    setNowSectionVisible_: function(visible) {
      $('google-now-launcher').hidden = !visible;
    },

    /**
     * Activates the Audio History section of the Settings page.
     * @param {boolean} visible Whether the audio history section is visible.
     * @param {string} labelText Text describing current audio history state.
     * @private
     */
    setAudioHistorySectionVisible_: function(visible, labelText) {
      $('audio-history').hidden = !visible;
      $('audio-history-label').textContent = labelText;
    },

    /**
     * Event listener for the 'homepage is NTP' preference. Updates the label
     * next to the 'Change' button.
     * @param {Event} event The preference change event.
     */
    onHomePageIsNtpChanged_: function(event) {
      if (!event.value.uncommitted) {
        $('home-page-url').hidden = event.value.value;
        $('home-page-ntp').hidden = !event.value.value;
      }
    },

    /**
     * Event listener for changes to the homepage preference. Updates the label
     * next to the 'Change' button.
     * @param {Event} event The preference change event.
     */
    onHomePageChanged_: function(event) {
      if (!event.value.uncommitted)
        $('home-page-url').textContent = this.stripHttp_(event.value.value);
    },

    /**
     * Removes the 'http://' from a URL, like the omnibox does. If the string
     * doesn't start with 'http://' it is returned unchanged.
     * @param {string} url The url to be processed
     * @return {string} The url with the 'http://' removed.
     */
    stripHttp_: function(url) {
      return url.replace(/^http:\/\//, '');
    },

    /**
     * Called when the value of the download.default_directory preference
     * changes.
     * @param {Event} event Change event.
     * @private
     */
    onDefaultDownloadDirectoryChanged_: function(event) {
      $('downloadLocationPath').value = event.value.value;
      if (cr.isChromeOS) {
        // On ChromeOS, replace /special/drive-<hash>/root with "Google Drive"
        // for remote files, /home/chronos/user/Downloads or
        // /home/chronos/u-<hash>/Downloads with "Downloads" for local paths,
        // and '/' with ' \u203a ' (angled quote sign) everywhere. The modified
        // path is used only for display purpose.
        var path = $('downloadLocationPath').value;
        path = path.replace(/^\/special\/drive[^\/]*\/root/, 'Google Drive');
        path = path.replace(/^\/home\/chronos\/(user|u-[^\/]*)\//, '');
        path = path.replace(/\//g, ' \u203a ');
        $('downloadLocationPath').value = path;
      }
      $('download-location-label').classList.toggle('disabled',
                                                    event.value.disabled);
      $('downloadLocationChangeButton').disabled = event.value.disabled;
    },

    /**
     * Update the Default Browsers section based on the current state.
     * @param {string} statusString Description of the current default state.
     * @param {boolean} isDefault Whether or not the browser is currently
     *     default.
     * @param {boolean} canBeDefault Whether or not the browser can be default.
     * @private
     */
    updateDefaultBrowserState_: function(statusString, isDefault,
                                         canBeDefault) {
      if (!cr.isChromeOS) {
        var label = $('default-browser-state');
        label.textContent = statusString;

        $('set-as-default-browser').hidden = !canBeDefault || isDefault;
      }
    },

    /**
     * Clears the search engine popup.
     * @private
     */
    clearSearchEngines_: function() {
      $('default-search-engine').textContent = '';
    },

    /**
     * Updates the search engine popup with the given entries.
     * @param {Array} engines List of available search engines.
     * @param {number} defaultValue The value of the current default engine.
     * @param {boolean} defaultManaged Whether the default search provider is
     *     managed. If true, the default search provider can't be changed.
     * @private
     */
    updateSearchEngines_: function(engines, defaultValue, defaultManaged) {
      this.clearSearchEngines_();
      var engineSelect = $('default-search-engine');
      engineSelect.disabled = defaultManaged;
      if (defaultManaged && defaultValue == -1)
        return;
      var engineCount = engines.length;
      var defaultIndex = -1;
      for (var i = 0; i < engineCount; i++) {
        var engine = engines[i];
        var option = new Option(engine.name, engine.index);
        if (defaultValue == option.value)
          defaultIndex = i;
        engineSelect.appendChild(option);
      }
      if (defaultIndex >= 0)
        engineSelect.selectedIndex = defaultIndex;
    },

    /**
     * Set the default search engine based on the popup selection.
     * @private
     */
    setDefaultSearchEngine_: function() {
      var engineSelect = $('default-search-engine');
      var selectedIndex = engineSelect.selectedIndex;
      if (selectedIndex >= 0) {
        var selection = engineSelect.options[selectedIndex];
        chrome.send('setDefaultSearchEngine', [String(selection.value)]);
      }
    },

    /**
     * Get the selected profile item from the profile list. This also works
     * correctly if the list is not displayed.
     * @return {?Object} The profile item object, or null if nothing is
     *     selected.
     * @private
     */
    getSelectedProfileItem_: function() {
      var profilesList = $('profiles-list');
      if (profilesList.hidden) {
        if (profilesList.dataModel.length > 0)
          return profilesList.dataModel.item(0);
      } else {
        return profilesList.selectedItem;
      }
      return null;
    },

    /**
     * Helper function to set the status of profile view buttons to disabled or
     * enabled, depending on the number of profiles and selection status of the
     * profiles list.
     * @private
     */
    setProfileViewButtonsStatus_: function() {
      var profilesList = $('profiles-list');
      var selectedProfile = profilesList.selectedItem;
      var hasSelection = selectedProfile != null;
      var hasSingleProfile = profilesList.dataModel.length == 1;
      $('profiles-manage').disabled = !hasSelection ||
          !selectedProfile.isCurrentProfile;
      if (hasSelection && !selectedProfile.isCurrentProfile)
        $('profiles-manage').title = loadTimeData.getString('currentUserOnly');
      else
        $('profiles-manage').title = '';
      $('profiles-delete').disabled = !profilesList.canDeleteItems ||
                                      !hasSelection;
      var importData = $('import-data');
      if (importData) {
        importData.disabled = $('import-data').disabled = hasSelection &&
          !selectedProfile.isCurrentProfile;
      }
    },

    /**
     * Display the correct dialog layout, depending on how many profiles are
     * available.
     * @param {number} numProfiles The number of profiles to display.
     * @private
     */
    setProfileViewSingle_: function(numProfiles) {
      // Always show the profiles list when using the new Profiles UI.
      var usingNewProfilesUI = loadTimeData.getBoolean('usingNewProfilesUI');
      var showSingleProfileView = !usingNewProfilesUI && numProfiles == 1;
      $('profiles-list').hidden = showSingleProfileView;
      $('profiles-single-message').hidden = !showSingleProfileView;
      $('profiles-manage').hidden = showSingleProfileView;
      $('profiles-delete').textContent = showSingleProfileView ?
          loadTimeData.getString('profilesDeleteSingle') :
          loadTimeData.getString('profilesDelete');
    },

    /**
     * Adds all |profiles| to the list.
     * @param {!Array<!options.Profile>} profiles An array of profile info
     *     objects.
     * @private
     */
    setProfilesInfo_: function(profiles) {
      this.setProfileViewSingle_(profiles.length);
      // add it to the list, even if the list is hidden so we can access it
      // later.
      $('profiles-list').dataModel = new ArrayDataModel(profiles);

      // Received new data. If showing the "manage" overlay, keep it up to
      // date. If showing the "delete" overlay, close it.
      if (ManageProfileOverlay.getInstance().visible &&
          !$('manage-profile-overlay-manage').hidden) {
        ManageProfileOverlay.showManageDialog(false);
      } else {
        ManageProfileOverlay.getInstance().visible = false;
      }

      this.setProfileViewButtonsStatus_();
    },

    /**
     * Reports supervised user import errors to the SupervisedUserImportOverlay.
     * @param {string} error The error message to display.
     * @private
     */
    showSupervisedUserImportError_: function(error) {
      SupervisedUserImportOverlay.onError(error);
    },

    /**
     * Reports successful importing of a supervised user to
     * the SupervisedUserImportOverlay.
     * @private
     */
    showSupervisedUserImportSuccess_: function() {
      SupervisedUserImportOverlay.onSuccess();
    },

    /**
     * Reports an error to the "create" overlay during profile creation.
     * @param {string} error The error message to display.
     * @private
     */
    showCreateProfileError_: function(error) {
      CreateProfileOverlay.onError(error);
    },

    /**
    * Sends a warning message to the "create" overlay during profile creation.
    * @param {string} warning The warning message to display.
    * @private
    */
    showCreateProfileWarning_: function(warning) {
      CreateProfileOverlay.onWarning(warning);
    },

    /**
    * Reports successful profile creation to the "create" overlay.
     * @param {options.Profile} profileInfo An object of the form:
     *     profileInfo = {
     *       name: "Profile Name",
     *       filePath: "/path/to/profile/data/on/disk"
     *       isSupervised: (true|false),
     *     };
    * @private
    */
    showCreateProfileSuccess_: function(profileInfo) {
      CreateProfileOverlay.onSuccess(profileInfo);
    },

    /**
     * Returns the currently active profile for this browser window.
     * @return {options.Profile} A profile info object.
     * @private
     */
    getCurrentProfile_: function() {
      for (var i = 0; i < $('profiles-list').dataModel.length; i++) {
        var profile = $('profiles-list').dataModel.item(i);
        if (profile.isCurrentProfile)
          return profile;
      }

      assertNotReached('There should always be a current profile.');
    },

    /**
     * Propmpts user to confirm deletion of the profile for this browser
     * window.
     * @private
     */
    deleteCurrentProfile_: function() {
      ManageProfileOverlay.showDeleteDialog(this.getCurrentProfile_());
    },

    /**
     * @param {boolean} enabled
     */
    setNativeThemeButtonEnabled_: function(enabled) {
      var button = $('themes-native-button');
      if (button)
        button.disabled = !enabled;
    },

    /**
     * @param {boolean} enabled
     */
    setThemesResetButtonEnabled_: function(enabled) {
      $('themes-reset').disabled = !enabled;
    },

    /**
     * @param {boolean} managed
     */
    setAccountPictureManaged_: function(managed) {
      var picture = $('account-picture');
      if (managed || UIAccountTweaks.loggedInAsGuest()) {
        picture.disabled = true;
        ChangePictureOptions.closeOverlay();
      } else {
        picture.disabled = false;
      }

      // Create a synthetic pref change event decorated as
      // CoreOptionsHandler::CreateValueForPref() does.
      var event = new Event('account-picture');
      if (managed)
        event.value = { controlledBy: 'policy' };
      else
        event.value = {};
      $('account-picture-indicator').handlePrefChange(event);
    },

    /**
     * (Re)loads IMG element with current user account picture.
     * @private
     */
    updateAccountPicture_: function() {
      var picture = $('account-picture');
      if (picture) {
        picture.src = 'chrome://userimage/' + this.username_ + '?id=' +
            Date.now();
      }
    },

    /**
     * @param {boolean} managed
     */
    setWallpaperManaged_: function(managed) {
      if (managed)
        $('set-wallpaper').disabled = true;
      else
        this.enableElementIfPossible_(getRequiredElement('set-wallpaper'));

      // Create a synthetic pref change event decorated as
      // CoreOptionsHandler::CreateValueForPref() does.
      var event = new Event('wallpaper');
      event.value = managed ? { controlledBy: 'policy' } : {};
      $('wallpaper-indicator').handlePrefChange(event);
    },

    /**
     * This enables or disables dependent settings in timezone section.
     * @private
     */
    updateTimezoneSectionState_: function() {
      var self = this;
      $('resolve-timezone-by-geolocation')
          .onclick = function(event) {
        self.resolveTimezoneByGeolocation_ = event.currentTarget.checked;
      };
      if (this.systemTimezoneIsManaged_) {
        $('resolve-timezone-by-geolocation').disabled = true;
        $('resolve-timezone-by-geolocation').checked = false;
      } else if (this.systemTimezoneAutomaticDetectionIsManaged_) {
        if (this.systemTimezoneAutomaticDetectionValue_ ==
            options.AutomaticTimezoneDetectionType.USERS_DECIDE) {
          $('resolve-timezone-by-geolocation').disabled = false;
          $('resolve-timezone-by-geolocation')
              .checked = this.resolveTimezoneByGeolocation_;
          $('timezone-value-select')
              .disabled = this.resolveTimezoneByGeolocation_;
        } else {
          $('resolve-timezone-by-geolocation').disabled = true;
          $('resolve-timezone-by-geolocation')
              .checked =
              (this.systemTimezoneAutomaticDetectionValue_ !=
               options.AutomaticTimezoneDetectionType.DISABLED);
          $('timezone-value-select').disabled = true;
        }
      } else {
        this.enableElementIfPossible_(
            getRequiredElement('resolve-timezone-by-geolocation'));
        $('timezone-value-select').disabled =
            this.resolveTimezoneByGeolocation_;
        $('resolve-timezone-by-geolocation')
            .checked = this.resolveTimezoneByGeolocation_;
      }
    },

    /**
     * This is called from chromium code when system timezone "managed" state
     * is changed. Enables or disables dependent settings.
     * @param {boolean} managed Is true when system Timezone is managed by
     *     enterprise policy. False otherwize.
     */
    setSystemTimezoneManaged_: function(managed) {
      this.systemTimezoneIsManaged_ = managed;
      this.updateTimezoneSectionState_();
    },

    /**
     * This is called from chromium code when system timezone detection
     * "managed" state is changed. Enables or disables dependent settings.
     * @param {boolean} managed Is true when system timezone autodetection is
     *     managed by enterprise policy. False otherwize.
     * @param {options.AutomaticTimezoneDetectionType} value Current value of
     *     SystemTimezoneAutomaticDetection device policy.
     */
    setSystemTimezoneAutomaticDetectionManaged_: function(managed, value) {
      this.systemTimezoneAutomaticDetectionIsManaged_ = managed;
      this.systemTimezoneAutomaticDetectionValue_ = value;
      this.updateTimezoneSectionState_();
    },

    /**
     * This is Preferences event listener, which is called when
     * kResolveTimezoneByGeolocation preference is changed.
     * Enables or disables dependent settings.
     * @param {Event} value New preference state.
     */
    onResolveTimezoneByGeolocationChanged_: function(value) {
      this.resolveTimezoneByGeolocation_ = value.value.value;
      this.updateTimezoneSectionState_();
    },

    /**
     * Handle the 'add device' button click.
     * @private
     */
    handleAddBluetoothDevice_: function() {
      chrome.send('coreOptionsUserMetricsAction',
                  ['Options_BluetoothShowAddDevice']);
      PageManager.showPageByName('bluetooth', false);
    },

    /**
     * Enables or disables the Manage SSL Certificates button.
     * @private
     */
    enableCertificateButton_: function(enabled) {
      $('certificatesManageButton').disabled = !enabled;
    },

    /**
     * Enables or disables the Chrome OS display settings button and overlay.
     * @param {boolean} uiEnabled
     * @param {boolean} unifiedEnabled
     * @param {boolean} mirroredEnabled
     * @private
     */
    enableDisplaySettings_: function(
        uiEnabled, unifiedEnabled, mirroredEnabled) {
      if (cr.isChromeOS) {
        $('display-options').disabled = !uiEnabled;
        DisplayOptions.getInstance().setEnabled(
            uiEnabled, unifiedEnabled, mirroredEnabled);
      }
    },

    /**
     * Enables factory reset section.
     * @private
     */
    enableFactoryResetSection_: function() {
      $('factory-reset-section').hidden = false;
    },

    /**
     * Set the checked state of the metrics reporting checkbox.
     * @private
     */
    setMetricsReportingCheckboxState_: function(checked,
                                                policyManaged,
                                                ownerManaged) {
      $('metrics-reporting-enabled').checked = checked;
      $('metrics-reporting-enabled').disabled = policyManaged || ownerManaged;

      // If checkbox gets disabled then add an attribute for displaying the
      // special icon. Otherwise remove the indicator attribute.
      if (policyManaged) {
        $('metrics-reporting-disabled-icon').setAttribute('controlled-by',
                                                          'policy');
      } else if (ownerManaged) {
        $('metrics-reporting-disabled-icon').setAttribute('controlled-by',
                                                          'owner');
      } else {
        $('metrics-reporting-disabled-icon').removeAttribute('controlled-by');
      }

    },

    /**
     * @private
     */
    setMetricsReportingSettingVisibility_: function(visible) {
      if (visible)
        $('metrics-reporting-setting').style.display = 'block';
      else
        $('metrics-reporting-setting').style.display = 'none';
    },

    /**
      * Set the checked state of the Safe Browsing Extended Reporting Enabled
      * checkbox.
      * @private
      */
    setExtendedReportingEnabledCheckboxState_: function(checked) {
      $('safeBrowsingExtendedReportingCheckbox').checked = checked;
    },

    /**
     * Set network prediction checkbox value.
     *
     * @param {{value: number, disabled: boolean}} pref Information about
     *     network prediction options. |pref.value| is the value of network
     *     prediction options. |pref.disabled| shows if the pref is not user
     *     modifiable.
     * @private
     */
    setNetworkPredictionValue_: function(pref) {
      var checkbox = $('networkPredictionOptions');
      checkbox.disabled = pref.disabled ||
                          loadTimeData.getBoolean('profileIsGuest');
      checkbox.checked = (pref.value != NetworkPredictionOptions.NEVER);
    },

    /**
     * Set the font size selected item. This item actually reflects two
     * preferences: the default font size and the default fixed font size.
     *
     * @param {{value: number, disabled: boolean, controlledBy: string}} pref
     *     Information about the font size preferences. |pref.value| is the
     *     value of the default font size pref. |pref.disabled| is true if
     *     either pref not user modifiable. |pref.controlledBy| is the source of
     *     the pref value(s) if either pref is currently not controlled by the
     *     user.
     * @private
     */
    setFontSize_: function(pref) {
      var selectCtl = /** @type {HTMLSelectElement} */($('defaultFontSize'));
      selectCtl.disabled = pref.disabled;
      // Create a synthetic pref change event decorated as
      // CoreOptionsHandler::CreateValueForPref() does.
      var event = new Event('synthetic-font-size');
      event.value = {
        value: pref.value,
        controlledBy: pref.controlledBy,
        disabled: pref.disabled
      };
      $('font-size-indicator').handlePrefChange(event);

      for (var i = 0; i < selectCtl.options.length; i++) {
        if (selectCtl.options[i].value == pref.value) {
          selectCtl.selectedIndex = i;
          if ($('Custom'))
            selectCtl.remove($('Custom').index);
          return;
        }
      }

      // Add/Select Custom Option in the font size label list.
      if (!$('Custom')) {
        var option = new Option(loadTimeData.getString('fontSizeLabelCustom'),
                                -1, false, true);
        option.setAttribute('id', 'Custom');
        selectCtl.add(option);
      }
      $('Custom').selected = true;
    },

    /**
     * Populate the page zoom selector with values received from the caller.
     * @param {Array} items An array of items to populate the selector.
     *     each object is an array with three elements as follows:
     *       0: The title of the item (string).
     *       1: The value of the item (number).
     *       2: Whether the item should be selected (boolean).
     * @private
     */
    setupPageZoomSelector_: function(items) {
      var element = $('defaultZoomFactor');

      // Remove any existing content.
      element.textContent = '';

      // Insert new child nodes into select element.
      var value, title, selected;
      for (var i = 0; i < items.length; i++) {
        title = items[i][0];
        value = items[i][1];
        selected = items[i][2];
        element.appendChild(new Option(title, value, false, selected));
      }
    },

    /**
     * Shows/hides the autoOpenFileTypesResetToDefault button and label, with
     * animation.
     * @param {boolean} display Whether to show the button and label or not.
     * @private
     */
    setAutoOpenFileTypesDisplayed_: function(display) {
      if ($('advanced-settings').hidden) {
        // If the Advanced section is hidden, don't animate the transition.
        $('auto-open-file-types-section').hidden = !display;
      } else {
        if (display) {
          this.showSectionWithAnimation_(
              $('auto-open-file-types-section'),
              $('auto-open-file-types-container'));
        } else {
          this.hideSectionWithAnimation_(
              $('auto-open-file-types-section'),
              $('auto-open-file-types-container'));
        }
      }
    },

    /**
     * Set the enabled state for the proxy settings button and its associated
     * message when extension controlled.
     * @param {boolean} disabled Whether the button should be disabled.
     * @param {boolean} extensionControlled Whether the proxy is extension
     *     controlled.
     * @private
     */
    setupProxySettingsButton_: function(disabled, extensionControlled) {
      if (!cr.isChromeOS) {
        $('proxiesConfigureButton').disabled = disabled;
        $('proxiesLabel').textContent =
            loadTimeData.getString(extensionControlled ?
                'proxiesLabelExtension' : 'proxiesLabelSystem');
      }
    },

    /**
     * Set the initial state of the spoken feedback checkbox.
     * @private
     */
    setSpokenFeedbackCheckboxState_: function(checked) {
      $('accessibility-spoken-feedback-check').checked = checked;
    },

    /**
     * Set the initial state of the high contrast checkbox.
     * @private
     */
    setHighContrastCheckboxState_: function(checked) {
      $('accessibility-high-contrast-check').checked = checked;
    },

    /**
     * Set the initial state of the virtual keyboard checkbox.
     * @private
     */
    setVirtualKeyboardCheckboxState_: function(checked) {
      // TODO(zork): Update UI
    },

    /**
     * Show/hide mouse settings slider.
     * @private
     */
    showMouseControls_: function(show) {
      $('mouse-settings').hidden = !show;
    },

    /**
     * Adds hidden warning boxes for settings potentially controlled by
     * extensions.
     * @param {string} parentDiv The div name to append the bubble to.
     * @param {string} bubbleId The ID to use for the bubble.
     * @param {boolean} first Add as first node if true, otherwise last.
     * @private
     */
    addExtensionControlledBox_: function(parentDiv, bubbleId, first) {
      var bubble = $('extension-controlled-warning-template').cloneNode(true);
      bubble.id = bubbleId;
      var parent = $(parentDiv);
      if (first)
        parent.insertBefore(bubble, parent.firstChild);
      else
        parent.appendChild(bubble);
    },

    /**
     * Adds a bubble showing that an extension is controlling a particular
     * setting.
     * @param {string} parentDiv The div name to append the bubble to.
     * @param {string} bubbleId The ID to use for the bubble.
     * @param {string} extensionId The ID of the controlling extension.
     * @param {string} extensionName The name of the controlling extension.
     * @private
     */
    toggleExtensionControlledBox_: function(
        parentDiv, bubbleId, extensionId, extensionName) {
      var bubble = $(bubbleId);
      assert(bubble);
      bubble.hidden = extensionId.length == 0;
      if (bubble.hidden)
        return;

      // Set the extension image.
      var div = bubble.firstElementChild;
      div.style.backgroundImage =
          'url(chrome://extension-icon/' + extensionId + '/24/1)';

      // Set the bubble label.
      var label = loadTimeData.getStringF('extensionControlled', extensionName);
      var docFrag = parseHtmlSubset('<div>' + label + '</div>', ['B', 'DIV']);
      div.innerHTML = docFrag.firstChild.innerHTML;

      // Wire up the button to disable the right extension.
      var button = div.nextElementSibling;
      button.dataset.extensionId = extensionId;
    },

    /**
     * Toggles the warning boxes that show which extension is controlling
     * various settings of Chrome.
     * @param {{searchEngine: options.ExtensionData,
     *          homePage: options.ExtensionData,
     *          startUpPage: options.ExtensionData,
     *          newTabPage: options.ExtensionData,
     *          proxy: options.ExtensionData}} details A dictionary of ID+name
     *     pairs for each of the settings controlled by an extension.
     * @private
     */
    toggleExtensionIndicators_: function(details) {
      this.toggleExtensionControlledBox_('search-section-content',
                                         'search-engine-controlled',
                                         details.searchEngine.id,
                                         details.searchEngine.name);
      this.toggleExtensionControlledBox_('extension-controlled-container',
                                         'homepage-controlled',
                                         details.homePage.id,
                                         details.homePage.name);
      this.toggleExtensionControlledBox_('startup-section-content',
                                         'startpage-controlled',
                                         details.startUpPage.id,
                                         details.startUpPage.name);
      this.toggleExtensionControlledBox_('newtab-section-content',
                                         'newtab-controlled',
                                         details.newTabPage.id,
                                         details.newTabPage.name);
      this.toggleExtensionControlledBox_('proxy-section-content',
                                         'proxy-controlled',
                                         details.proxy.id,
                                         details.proxy.name);

      // The proxy section contains just the warning box and nothing else, so
      // if we're hiding the proxy warning box, we should also hide its header
      // section.
      $('proxy-section').hidden = details.proxy.id.length == 0;
    },


    /**
     * Show/hide touchpad-related settings.
     * @private
     */
    showTouchpadControls_: function(show) {
      $('touchpad-settings').hidden = !show;
      $('accessibility-tap-dragging').hidden = !show;
    },

    /**
     * Sets the state of the checkbox indicating if Bluetooth is turned on. The
     * state of the "Find devices" button and the list of discovered devices may
     * also be affected by a change to the state.
     * @param {boolean} checked Flag Indicating if Bluetooth is turned on.
     * @private
     */
    setBluetoothState_: function(checked) {
      $('enable-bluetooth').checked = checked;
      $('bluetooth-paired-devices-list').parentNode.hidden = !checked;
      $('bluetooth-add-device').hidden = !checked;
      $('bluetooth-reconnect-device').hidden = !checked;
    },

    /**
     * Process a bluetooth.onAdapterStateChanged event.
     * @param {!chrome.bluetooth.AdapterState} state
     * @private
     */
    onBluetoothAdapterStateChanged_: function(state) {
      var disallowBluetooth = !loadTimeData.getBoolean('allowBluetooth');
      // If allowBluetooth is false, state.available will always be false, so
      // assume Bluetooth is available but disabled by policy.
      if (!state || (!state.available && !disallowBluetooth)) {
        this.bluetoothAdapterState_ = null;
        $('bluetooth-devices').hidden = true;
        return;
      }
      $('bluetooth-devices').hidden = false;
      this.bluetoothAdapterState_ = state;
      this.setBluetoothState_(state.powered);

      var enableBluetoothEl = $('enable-bluetooth');
      if (disallowBluetooth) {
        enableBluetoothEl.setAttribute('pref', 'cros.device.allow_bluetooth');
        enableBluetoothEl.setAttribute('controlled-by', 'policy');
        enableBluetoothEl.disabled = true;
        $('bluetooth-controlled-setting-indicator').hidden = false;
        return;
      }
      enableBluetoothEl.removeAttribute('pref');
      enableBluetoothEl.removeAttribute('controlled-by');
      enableBluetoothEl.disabled = false;
      $('bluetooth-controlled-setting-indicator').hidden = true;

      // Flush the device lists.
      $('bluetooth-paired-devices-list').clear();
      $('bluetooth-unpaired-devices-list').clear();
      if (state.powered) {
        options.BluetoothOptions.updateDiscoveryState(state.discovering);
        // Update the device lists.
        chrome.bluetooth.getDevices(function(devices) {
          for (var device of devices)
            this.updateBluetoothDevicesList_(device);
        }.bind(this));
      } else {
        options.BluetoothOptions.dismissOverlay();
      }
    },

    /**
     * Process a bluetooth.onDeviceAdded or onDeviceChanged event and update the
     * device list.
     * @param {!chrome.bluetooth.Device} device
     * @private
     */
    onBluetoothDeviceAddedOrChanged_: function(device) {
      this.updateBluetoothDevicesList_(device);
    },

    /**
     * Process a bluetooth.onDeviceRemoved event and update the device list.
     * @param {!chrome.bluetooth.Device} device
     * @private
     */
    onBluetoothDeviceRemoved_: function(device) {
      this.removeBluetoothDevice_(device.address);
    },

    /**
     * Process a bluetoothPrivate onPairing event and update the device list.
     * @param {!chrome.bluetoothPrivate.PairingEvent} pairing_event
     * @private
     */
    onBluetoothPrivatePairing_: function(pairing_event) {
      this.updateBluetoothDevicesList_(pairing_event.device);
      BluetoothPairing.onBluetoothPairingEvent(pairing_event);
    },

    /**
     * Add |device| to the appropriate list of Bluetooth devices.
     * @param {!chrome.bluetooth.Device} device
     * @private
     */
    addBluetoothDeviceToList_: function(device) {
      // Display the "connecting" (already paired or not yet paired) and the
      // paired devices in the same list.
      if (device.paired || device.connecting)
        $('bluetooth-paired-devices-list').appendDevice(device);
      else
        $('bluetooth-unpaired-devices-list').appendDevice(device);
    },

    /**
     * Add |device| to the appropriate list of Bluetooth devices or update the
     * entry if a device with a matching |address| property exists.
     * @param {!chrome.bluetooth.Device} device
     * @private
     */
    updateBluetoothDevicesList_: function(device) {
      // Display the "connecting" (already paired or not yet paired) and the
      // paired devices in the same list.
      if (device.paired || device.connecting) {
        // Test to see if the device is currently in the unpaired list, in which
        // case it should be removed from that list.
        var index = $('bluetooth-unpaired-devices-list').find(device.address);
        if (index != undefined)
          $('bluetooth-unpaired-devices-list').deleteItemAtIndex(index);
      } else {
        // Test to see if the device is currently in the paired list, in which
        // case it should be removed from that list.
        var index = $('bluetooth-paired-devices-list').find(device.address);
        if (index != undefined)
          $('bluetooth-paired-devices-list').deleteItemAtIndex(index);
      }
      this.addBluetoothDeviceToList_(device);
    },

    /**
     * Removes an element from the list of available devices.
     * @param {string} address Unique address of the device.
     * @private
     */
    removeBluetoothDevice_: function(address) {
      var index = $('bluetooth-unpaired-devices-list').find(address);
      if (index != undefined) {
        $('bluetooth-unpaired-devices-list').deleteItemAtIndex(index);
      } else {
        index = $('bluetooth-paired-devices-list').find(address);
        if (index != undefined)
          $('bluetooth-paired-devices-list').deleteItemAtIndex(index);
      }
    },

    /**
     * Shows the overlay dialog for changing the user avatar image.
     * @private
     */
    showImagerPickerOverlay_: function() {
      PageManager.showPageByName('changePicture');
    },

    /**
     * Shows (or not) the "User" section of the settings page based on whether
     * any of the sub-sections are present (or not).
     * @private
     */
    maybeShowUserSection_: function() {
      $('sync-users-section').hidden =
          $('profiles-section').hidden &&
          $('sync-section').hidden &&
          $('profiles-supervised-dashboard-tip').hidden;
    },

    /**
     * Updates the date and time section with time sync information.
     * @param {boolean} canSetTime Whether the system time can be set.
     * @private
     */
    setCanSetTime_: function(canSetTime) {
      // If the time has been network-synced, it cannot be set manually.
      $('set-time').hidden = !canSetTime;
    },

    /**
     * Handle the 'set date and time' button click.
     * @private
     */
    handleSetTime_: function() {
      chrome.send('showSetTime');
    },

    /**
     * Enables the given element if possible; on Chrome OS, it won't enable
     * an element that must stay disabled for the session type.
     * @param {!Element} element Element to enable.
     */
    enableElementIfPossible_: function(element) {
      if (cr.isChromeOS)
        UIAccountTweaks.enableElementIfPossible(element);
      else
        element.disabled = false;
    },
  };

  // Forward public APIs to private implementations.
  cr.makePublic(BrowserOptions, [
    'deleteCurrentProfile',
    'enableCertificateButton',
    'enableDisplaySettings',
    'enableFactoryResetSection',
    'getCurrentProfile',
    'getStartStopSyncButton',
    'notifyInitializationComplete',
    'removeBluetoothDevice',
    'scrollToSection',
    'setAccountPictureManaged',
    'setAllHotwordSectionsVisible',
    'setAudioHistorySectionVisible',
    'setAutoOpenFileTypesDisplayed',
    'setCanSetTime',
    'setExtendedReportingEnabledCheckboxState',
    'setFontSize',
    'setHighContrastCheckboxState',
    'setHotwordRetrainLinkVisible',
    'setMetricsReportingCheckboxState',
    'setMetricsReportingSettingVisibility',
    'setNativeThemeButtonEnabled',
    'setNetworkPredictionValue',
    'setNowSectionVisible',
    'setProfilesInfo',
    'setSpokenFeedbackCheckboxState',
    'setSystemTimezoneAutomaticDetectionManaged',
    'setSystemTimezoneManaged',
    'setThemesResetButtonEnabled',
    'setVirtualKeyboardCheckboxState',
    'setWallpaperManaged',
    'setupPageZoomSelector',
    'setupProxySettingsButton',
    'showCreateProfileError',
    'showCreateProfileSuccess',
    'showCreateProfileWarning',
    'showHotwordAlwaysOnSection',
    'showHotwordNoDspSection',
    'showHotwordSection',
    'showMouseControls',
    'showSupervisedUserImportError',
    'showSupervisedUserImportSuccess',
    'showTouchpadControls',
    'toggleExtensionIndicators',
    'updateAccountPicture',
    'updateDefaultBrowserState',
    'updateEasyUnlock',
    'updateManagesSupervisedUsers',
    'updateSearchEngines',
    'updateSyncState',
  ]);

  if (cr.isChromeOS) {
    /**
     * Returns username (canonical email) of the user logged in (ChromeOS only).
     * @return {string} user email.
     */
    // TODO(jhawkins): Investigate the use case for this method.
    BrowserOptions.getLoggedInUsername = function() {
      return BrowserOptions.getInstance().username_;
    };

    /**
     * Shows Android Apps settings when they are available.
     * (Chrome OS only).
     */
    BrowserOptions.showAndroidAppsSection = function(isArcEnabled) {
      var section = $('android-apps-section');
      if (!section)
        return;

      section.hidden = false;
    };

    /**
     * Shows/hides Android Settings app section.
     * (Chrome OS only).
     */
    BrowserOptions.setAndroidAppsSettingsVisibility = function(isVisible) {
      var settings = $('android-apps-settings');
      if (!settings)
        return;

      settings.hidden = !isVisible;
    };
  }

  // Export
  return {
    BrowserOptions: BrowserOptions
  };
});
