Home | History | Annotate | Download | only in options
      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 #include "chrome/browser/ui/webui/options/browser_options_handler.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/bind.h"
     12 #include "base/bind_helpers.h"
     13 #include "base/command_line.h"
     14 #include "base/memory/singleton.h"
     15 #include "base/metrics/field_trial.h"
     16 #include "base/metrics/histogram.h"
     17 #include "base/path_service.h"
     18 #include "base/prefs/pref_service.h"
     19 #include "base/stl_util.h"
     20 #include "base/strings/string_number_conversions.h"
     21 #include "base/strings/utf_string_conversions.h"
     22 #include "base/value_conversions.h"
     23 #include "base/values.h"
     24 #include "chrome/browser/auto_launch_trial.h"
     25 #include "chrome/browser/browser_process.h"
     26 #include "chrome/browser/chrome_notification_types.h"
     27 #include "chrome/browser/chrome_page_zoom.h"
     28 #include "chrome/browser/custom_home_pages_table_model.h"
     29 #include "chrome/browser/download/download_prefs.h"
     30 #include "chrome/browser/gpu/gpu_mode_manager.h"
     31 #include "chrome/browser/lifetime/application_lifetime.h"
     32 #include "chrome/browser/managed_mode/managed_user_registration_utility.h"
     33 #include "chrome/browser/managed_mode/managed_user_service.h"
     34 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
     35 #include "chrome/browser/prefs/scoped_user_pref_update.h"
     36 #include "chrome/browser/prefs/session_startup_pref.h"
     37 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
     38 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
     39 #include "chrome/browser/printing/cloud_print/cloud_print_url.h"
     40 #include "chrome/browser/profiles/profile.h"
     41 #include "chrome/browser/profiles/profile_info_cache.h"
     42 #include "chrome/browser/profiles/profile_info_util.h"
     43 #include "chrome/browser/profiles/profile_metrics.h"
     44 #include "chrome/browser/profiles/profile_shortcut_manager.h"
     45 #include "chrome/browser/profiles/profile_window.h"
     46 #include "chrome/browser/profiles/profiles_state.h"
     47 #include "chrome/browser/search/search.h"
     48 #include "chrome/browser/search_engines/template_url.h"
     49 #include "chrome/browser/search_engines/template_url_service.h"
     50 #include "chrome/browser/search_engines/template_url_service_factory.h"
     51 #include "chrome/browser/service/service_process_control.h"
     52 #include "chrome/browser/signin/signin_manager.h"
     53 #include "chrome/browser/signin/signin_manager_factory.h"
     54 #include "chrome/browser/sync/profile_sync_service.h"
     55 #include "chrome/browser/sync/profile_sync_service_factory.h"
     56 #include "chrome/browser/sync/sync_ui_util.h"
     57 #include "chrome/browser/themes/theme_service.h"
     58 #include "chrome/browser/themes/theme_service_factory.h"
     59 #include "chrome/browser/ui/browser_finder.h"
     60 #include "chrome/browser/ui/chrome_select_file_policy.h"
     61 #include "chrome/browser/ui/host_desktop.h"
     62 #include "chrome/browser/ui/options/options_util.h"
     63 #include "chrome/browser/ui/webui/favicon_source.h"
     64 #include "chrome/common/chrome_constants.h"
     65 #include "chrome/common/chrome_paths.h"
     66 #include "chrome/common/chrome_switches.h"
     67 #include "chrome/common/net/url_fixer_upper.h"
     68 #include "chrome/common/pref_names.h"
     69 #include "chrome/common/url_constants.h"
     70 #include "chromeos/chromeos_switches.h"
     71 #include "content/public/browser/browser_thread.h"
     72 #include "content/public/browser/download_manager.h"
     73 #include "content/public/browser/navigation_controller.h"
     74 #include "content/public/browser/notification_details.h"
     75 #include "content/public/browser/notification_service.h"
     76 #include "content/public/browser/notification_source.h"
     77 #include "content/public/browser/notification_types.h"
     78 #include "content/public/browser/url_data_source.h"
     79 #include "content/public/browser/user_metrics.h"
     80 #include "content/public/browser/web_contents.h"
     81 #include "content/public/browser/web_contents_view.h"
     82 #include "content/public/common/page_zoom.h"
     83 #include "google_apis/gaia/google_service_auth_error.h"
     84 #include "grit/chromium_strings.h"
     85 #include "grit/generated_resources.h"
     86 #include "grit/locale_settings.h"
     87 #include "grit/theme_resources.h"
     88 #include "third_party/skia/include/core/SkBitmap.h"
     89 #include "ui/base/l10n/l10n_util.h"
     90 #include "ui/webui/web_ui_util.h"
     91 
     92 #if !defined(OS_CHROMEOS)
     93 #include "chrome/browser/ui/webui/options/advanced_options_utils.h"
     94 #endif
     95 
     96 #if defined(OS_CHROMEOS)
     97 #include "ash/magnifier/magnifier_constants.h"
     98 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
     99 #include "chrome/browser/chromeos/extensions/wallpaper_manager_util.h"
    100 #include "chrome/browser/chromeos/login/user_manager.h"
    101 #include "chrome/browser/chromeos/settings/cros_settings.h"
    102 #include "chrome/browser/policy/browser_policy_connector.h"
    103 #include "chrome/browser/ui/browser_window.h"
    104 #include "chrome/browser/ui/webui/options/chromeos/timezone_options_util.h"
    105 #include "chromeos/dbus/dbus_thread_manager.h"
    106 #include "chromeos/dbus/power_manager_client.h"
    107 #include "ui/gfx/image/image_skia.h"
    108 #endif  // defined(OS_CHROMEOS)
    109 
    110 #if defined(OS_WIN)
    111 #include "chrome/installer/util/auto_launch_util.h"
    112 #endif  // defined(OS_WIN)
    113 
    114 using content::BrowserContext;
    115 using content::BrowserThread;
    116 using content::DownloadManager;
    117 using content::OpenURLParams;
    118 using content::Referrer;
    119 using content::UserMetricsAction;
    120 
    121 namespace options {
    122 
    123 namespace {
    124 
    125 // Constants for the new tab button field trial.
    126 const char kProfileResetTrialName[] = "ManualResetProfile";
    127 const char kProfileResetTrialEnableGroupName[] = "Enable";
    128 
    129 bool ShouldShowMultiProfilesUserList(chrome::HostDesktopType desktop_type) {
    130 #if defined(OS_CHROMEOS)
    131   // On Chrome OS we use different UI for multi-profiles.
    132   return false;
    133 #else
    134   if (desktop_type != chrome::HOST_DESKTOP_TYPE_NATIVE)
    135     return false;
    136   return profiles::IsMultipleProfilesEnabled();
    137 #endif
    138 }
    139 
    140 void CreateDesktopShortcutForProfile(Profile* profile,
    141                                      Profile::CreateStatus status) {
    142   ProfileShortcutManager* shortcut_manager =
    143       g_browser_process->profile_manager()->profile_shortcut_manager();
    144   if (shortcut_manager)
    145     shortcut_manager->CreateProfileShortcut(profile->GetPath());
    146 }
    147 
    148 void RunProfileCreationCallbacks(
    149     const std::vector<ProfileManager::CreateCallback>& callbacks,
    150     Profile* profile,
    151     Profile::CreateStatus status) {
    152   std::vector<ProfileManager::CreateCallback>::const_iterator it;
    153   for (it = callbacks.begin(); it != callbacks.end(); ++it) {
    154     it->Run(profile, status);
    155   }
    156 }
    157 
    158 void OpenNewWindowForProfile(
    159     chrome::HostDesktopType desktop_type,
    160     Profile* profile,
    161     Profile::CreateStatus status) {
    162   if (status != Profile::CREATE_STATUS_INITIALIZED)
    163     return;
    164 
    165   profiles::FindOrCreateNewWindowForProfile(
    166     profile,
    167     chrome::startup::IS_PROCESS_STARTUP,
    168     chrome::startup::IS_FIRST_RUN,
    169     desktop_type,
    170     false);
    171 }
    172 
    173 }  // namespace
    174 
    175 BrowserOptionsHandler::BrowserOptionsHandler()
    176     : page_initialized_(false),
    177       template_url_service_(NULL),
    178       weak_ptr_factory_(this) {
    179 #if !defined(OS_MACOSX)
    180   default_browser_worker_ = new ShellIntegration::DefaultBrowserWorker(this);
    181 #endif
    182 
    183 #if defined(ENABLE_FULL_PRINTING)
    184 #if !defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN)
    185   // On Windows, we need the PDF plugin which is only guaranteed to exist on
    186   // Google Chrome builds. Use a command-line switch for Windows non-Google
    187   //  Chrome builds.
    188   cloud_print_connector_ui_enabled_ =
    189       CommandLine::ForCurrentProcess()->HasSwitch(
    190       switches::kEnableCloudPrintProxy);
    191 #elif !defined(OS_CHROMEOS)
    192   // Always enabled for Mac, Linux and Google Chrome Windows builds.
    193   // Never enabled for Chrome OS, we don't even need to indicate it.
    194   cloud_print_connector_ui_enabled_ = true;
    195 #endif
    196 #endif  // defined(ENABLE_FULL_PRINTING)
    197 }
    198 
    199 BrowserOptionsHandler::~BrowserOptionsHandler() {
    200   CancelProfileRegistration(false);
    201   ProfileSyncService* sync_service(ProfileSyncServiceFactory::
    202       GetInstance()->GetForProfile(Profile::FromWebUI(web_ui())));
    203   if (sync_service)
    204     sync_service->RemoveObserver(this);
    205 
    206   if (default_browser_worker_.get())
    207     default_browser_worker_->ObserverDestroyed();
    208   if (template_url_service_)
    209     template_url_service_->RemoveObserver(this);
    210   // There may be pending file dialogs, we need to tell them that we've gone
    211   // away so they don't try and call back to us.
    212   if (select_folder_dialog_.get())
    213     select_folder_dialog_->ListenerDestroyed();
    214 }
    215 
    216 void BrowserOptionsHandler::GetLocalizedValues(DictionaryValue* values) {
    217   DCHECK(values);
    218 
    219   static OptionsStringResource resources[] = {
    220     { "advancedSectionTitleCloudPrint", IDS_GOOGLE_CLOUD_PRINT },
    221     { "currentUserOnly", IDS_OPTIONS_CURRENT_USER_ONLY },
    222     { "advancedSectionTitleContent",
    223       IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT },
    224     { "advancedSectionTitleLanguages",
    225       IDS_OPTIONS_ADVANCED_SECTION_TITLE_LANGUAGES },
    226     { "advancedSectionTitleNetwork",
    227       IDS_OPTIONS_ADVANCED_SECTION_TITLE_NETWORK },
    228     { "advancedSectionTitlePrivacy",
    229       IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY },
    230     { "advancedSectionTitleSecurity",
    231       IDS_OPTIONS_ADVANCED_SECTION_TITLE_SECURITY },
    232     { "autofillEnabled", IDS_OPTIONS_AUTOFILL_ENABLE },
    233     { "autologinEnabled", IDS_OPTIONS_PASSWORDS_AUTOLOGIN },
    234     { "autoOpenFileTypesInfo", IDS_OPTIONS_OPEN_FILE_TYPES_AUTOMATICALLY },
    235     { "autoOpenFileTypesResetToDefault",
    236       IDS_OPTIONS_AUTOOPENFILETYPES_RESETTODEFAULT },
    237     { "changeHomePage", IDS_OPTIONS_CHANGE_HOME_PAGE },
    238     { "certificatesManageButton", IDS_OPTIONS_CERTIFICATES_MANAGE_BUTTON },
    239     { "customizeSync", IDS_OPTIONS_CUSTOMIZE_SYNC_BUTTON_LABEL },
    240     { "defaultFontSizeLabel", IDS_OPTIONS_DEFAULT_FONT_SIZE_LABEL },
    241     { "defaultSearchManageEngines", IDS_OPTIONS_DEFAULTSEARCH_MANAGE_ENGINES },
    242     { "defaultZoomFactorLabel", IDS_OPTIONS_DEFAULT_ZOOM_LEVEL_LABEL },
    243 #if defined(OS_CHROMEOS)
    244     { "disableGData", IDS_OPTIONS_DISABLE_GDATA },
    245 #endif
    246     { "disableWebServices", IDS_OPTIONS_DISABLE_WEB_SERVICES },
    247 #if defined(OS_CHROMEOS)
    248     { "displayOptions",
    249       IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_BUTTON_LABEL },
    250 #endif
    251     { "doNotTrack", IDS_OPTIONS_ENABLE_DO_NOT_TRACK },
    252     { "doNotTrackConfirmMessage", IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_TEXT },
    253     { "doNotTrackConfirmEnable",
    254        IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_ENABLE },
    255     { "doNotTrackConfirmDisable",
    256        IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_DISABLE },
    257     { "downloadLocationAskForSaveLocation",
    258       IDS_OPTIONS_DOWNLOADLOCATION_ASKFORSAVELOCATION },
    259     { "downloadLocationBrowseTitle",
    260       IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE },
    261     { "downloadLocationChangeButton",
    262       IDS_OPTIONS_DOWNLOADLOCATION_CHANGE_BUTTON },
    263     { "downloadLocationGroupName", IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME },
    264     { "enableLogging", IDS_OPTIONS_ENABLE_LOGGING },
    265     { "fontSettingsCustomizeFontsButton",
    266       IDS_OPTIONS_FONTSETTINGS_CUSTOMIZE_FONTS_BUTTON },
    267     { "fontSizeLabelCustom", IDS_OPTIONS_FONT_SIZE_LABEL_CUSTOM },
    268     { "fontSizeLabelLarge", IDS_OPTIONS_FONT_SIZE_LABEL_LARGE },
    269     { "fontSizeLabelMedium", IDS_OPTIONS_FONT_SIZE_LABEL_MEDIUM },
    270     { "fontSizeLabelSmall", IDS_OPTIONS_FONT_SIZE_LABEL_SMALL },
    271     { "fontSizeLabelVeryLarge", IDS_OPTIONS_FONT_SIZE_LABEL_VERY_LARGE },
    272     { "fontSizeLabelVerySmall", IDS_OPTIONS_FONT_SIZE_LABEL_VERY_SMALL },
    273     { "hideAdvancedSettings", IDS_SETTINGS_HIDE_ADVANCED_SETTINGS },
    274     { "homePageNtp", IDS_OPTIONS_HOMEPAGE_NTP },
    275     { "homePageShowHomeButton", IDS_OPTIONS_TOOLBAR_SHOW_HOME_BUTTON },
    276     { "homePageUseNewTab", IDS_OPTIONS_HOMEPAGE_USE_NEWTAB },
    277     { "homePageUseURL", IDS_OPTIONS_HOMEPAGE_USE_URL },
    278     { "importData", IDS_OPTIONS_IMPORT_DATA_BUTTON },
    279     { "improveBrowsingExperience", IDS_OPTIONS_IMPROVE_BROWSING_EXPERIENCE },
    280     { "languageAndSpellCheckSettingsButton",
    281       IDS_OPTIONS_SETTINGS_LANGUAGE_AND_INPUT_SETTINGS },
    282     { "linkDoctorPref", IDS_OPTIONS_LINKDOCTOR_PREF },
    283     { "manageAutofillSettings", IDS_OPTIONS_MANAGE_AUTOFILL_SETTINGS_LINK },
    284     { "manageLanguages", IDS_OPTIONS_TRANSLATE_MANAGE_LANGUAGES },
    285     { "managePasswords", IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK },
    286     { "networkPredictionEnabledDescription",
    287       IDS_NETWORK_PREDICTION_ENABLED_DESCRIPTION },
    288     { "passwordsAndAutofillGroupName",
    289       IDS_OPTIONS_PASSWORDS_AND_FORMS_GROUP_NAME },
    290     { "passwordManagerEnabled", IDS_OPTIONS_PASSWORD_MANAGER_ENABLE },
    291     { "passwordGenerationEnabledDescription",
    292       IDS_OPTIONS_PASSWORD_GENERATION_ENABLED_LABEL },
    293     { "privacyClearDataButton", IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON },
    294     { "privacyContentSettingsButton",
    295       IDS_OPTIONS_PRIVACY_CONTENT_SETTINGS_BUTTON },
    296     { "profilesCreate", IDS_PROFILES_CREATE_BUTTON_LABEL },
    297     { "profilesDelete", IDS_PROFILES_DELETE_BUTTON_LABEL },
    298     { "profilesDeleteSingle", IDS_PROFILES_DELETE_SINGLE_BUTTON_LABEL },
    299     { "profilesListItemCurrent", IDS_PROFILES_LIST_ITEM_CURRENT },
    300     { "profilesManage", IDS_PROFILES_MANAGE_BUTTON_LABEL },
    301 #if defined(ENABLE_SETTINGS_APP)
    302     { "profilesAppListSwitch", IDS_SETTINGS_APP_PROFILES_SWITCH_BUTTON_LABEL },
    303 #endif
    304     { "proxiesLabelExtension", IDS_OPTIONS_EXTENSION_PROXIES_LABEL },
    305     { "proxiesLabelSystem", IDS_OPTIONS_SYSTEM_PROXIES_LABEL,
    306       IDS_PRODUCT_NAME },
    307     { "resetProfileSettings", IDS_RESET_PROFILE_SETTINGS_BUTTON },
    308     { "resetProfileSettingsDescription",
    309       IDS_RESET_PROFILE_SETTINGS_DESCRIPTION },
    310     { "resetProfileSettingsSectionTitle",
    311       IDS_RESET_PROFILE_SETTINGS_SECTION_TITLE },
    312     { "safeBrowsingEnableProtection",
    313       IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION },
    314     { "sectionTitleAppearance", IDS_APPEARANCE_GROUP_NAME },
    315     { "sectionTitleDefaultBrowser", IDS_OPTIONS_DEFAULTBROWSER_GROUP_NAME },
    316     { "sectionTitleUsers", IDS_PROFILES_OPTIONS_GROUP_NAME },
    317     { "sectionTitleSearch", IDS_OPTIONS_DEFAULTSEARCH_GROUP_NAME },
    318     { "sectionTitleStartup", IDS_OPTIONS_STARTUP_GROUP_NAME },
    319     { "sectionTitleSync", IDS_SYNC_OPTIONS_GROUP_NAME },
    320     { "spellingConfirmMessage", IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TEXT },
    321     { "spellingConfirmEnable", IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_ENABLE },
    322     { "spellingConfirmDisable", IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_DISABLE },
    323     { "spellingPref", IDS_OPTIONS_SPELLING_PREF },
    324     { "startupRestoreLastSession", IDS_OPTIONS_STARTUP_RESTORE_LAST_SESSION },
    325     { "settingsTitle", IDS_SETTINGS_TITLE },
    326     { "showAdvancedSettings", IDS_SETTINGS_SHOW_ADVANCED_SETTINGS },
    327     { "sslCheckRevocation", IDS_OPTIONS_SSL_CHECKREVOCATION },
    328     { "startupSetPages", IDS_OPTIONS_STARTUP_SET_PAGES },
    329     { "startupShowNewTab", IDS_OPTIONS_STARTUP_SHOW_NEWTAB },
    330     { "startupShowPages", IDS_OPTIONS_STARTUP_SHOW_PAGES },
    331     { "suggestPref", IDS_OPTIONS_SUGGEST_PREF },
    332     { "syncButtonTextInProgress", IDS_SYNC_NTP_SETUP_IN_PROGRESS },
    333     { "syncButtonTextStop", IDS_SYNC_STOP_SYNCING_BUTTON_LABEL },
    334     { "themesGallery", IDS_THEMES_GALLERY_BUTTON },
    335     { "themesGalleryURL", IDS_THEMES_GALLERY_URL },
    336     { "tabsToLinksPref", IDS_OPTIONS_TABS_TO_LINKS_PREF },
    337     { "toolbarShowBookmarksBar", IDS_OPTIONS_TOOLBAR_SHOW_BOOKMARKS_BAR },
    338     { "toolbarShowHomeButton", IDS_OPTIONS_TOOLBAR_SHOW_HOME_BUTTON },
    339     { "translateEnableTranslate",
    340       IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE },
    341 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
    342     { "showWindowDecorations", IDS_SHOW_WINDOW_DECORATIONS },
    343     { "themesNativeButton", IDS_THEMES_GTK_BUTTON },
    344     { "themesSetClassic", IDS_THEMES_SET_CLASSIC },
    345 #else
    346     { "themes", IDS_THEMES_GROUP_NAME },
    347 #endif
    348     { "themesReset", IDS_THEMES_RESET_BUTTON },
    349 #if defined(OS_CHROMEOS)
    350     { "accessibilityExplanation",
    351       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_EXPLANATION },
    352     { "accessibilityHighContrast",
    353       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_HIGH_CONTRAST_DESCRIPTION },
    354     { "accessibilityScreenMagnifier",
    355       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_DESCRIPTION },
    356     { "accessibilityTapDragging",
    357       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TOUCHPAD_TAP_DRAGGING_DESCRIPTION },
    358     { "accessibilityScreenMagnifierOff",
    359       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_OFF },
    360     { "accessibilityScreenMagnifierFull",
    361       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_FULL },
    362     { "accessibilityScreenMagnifierPartial",
    363       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_PARTIAL },
    364     { "accessibilityLargeCursor",
    365       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_LARGE_CURSOR_DESCRIPTION },
    366     { "accessibilityStickyKeys",
    367       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_STICKY_KEYS_DESCRIPTION },
    368     { "accessibilitySpokenFeedback",
    369       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SPOKEN_FEEDBACK_DESCRIPTION },
    370     { "accessibilityTitle",
    371       IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY },
    372     { "accessibilityVirtualKeyboard",
    373       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_VIRTUAL_KEYBOARD_DESCRIPTION },
    374     { "accessibilityAlwaysShowMenu",
    375       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SHOULD_ALWAYS_SHOW_MENU },
    376     { "factoryResetHeading", IDS_OPTIONS_FACTORY_RESET_HEADING },
    377     { "factoryResetTitle", IDS_OPTIONS_FACTORY_RESET },
    378     { "factoryResetRestart", IDS_OPTIONS_FACTORY_RESET_BUTTON },
    379     { "factoryResetDataRestart", IDS_RELAUNCH_BUTTON },
    380     { "factoryResetWarning", IDS_OPTIONS_FACTORY_RESET_WARNING },
    381     { "factoryResetHelpUrl", IDS_FACTORY_RESET_HELP_URL },
    382     { "changePicture", IDS_OPTIONS_CHANGE_PICTURE_CAPTION },
    383     { "datetimeTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME },
    384     { "deviceGroupDescription", IDS_OPTIONS_DEVICE_GROUP_DESCRIPTION },
    385     { "deviceGroupPointer", IDS_OPTIONS_DEVICE_GROUP_POINTER_SECTION },
    386     { "mouseSpeed", IDS_OPTIONS_SETTINGS_MOUSE_SPEED_DESCRIPTION },
    387     { "touchpadSpeed", IDS_OPTIONS_SETTINGS_TOUCHPAD_SPEED_DESCRIPTION },
    388     { "enableScreenlock", IDS_OPTIONS_ENABLE_SCREENLOCKER_CHECKBOX },
    389     { "internetOptionsButtonTitle", IDS_OPTIONS_INTERNET_OPTIONS_BUTTON_TITLE },
    390     { "keyboardSettingsButtonTitle",
    391       IDS_OPTIONS_DEVICE_GROUP_KEYBOARD_SETTINGS_BUTTON_TITLE },
    392     { "manageAccountsButtonTitle", IDS_OPTIONS_ACCOUNTS_BUTTON_TITLE },
    393     { "noPointingDevices", IDS_OPTIONS_NO_POINTING_DEVICES },
    394     { "sectionTitleDevice", IDS_OPTIONS_DEVICE_GROUP_NAME },
    395     { "sectionTitleInternet", IDS_OPTIONS_INTERNET_OPTIONS_GROUP_LABEL },
    396     { "syncOverview", IDS_SYNC_OVERVIEW },
    397     { "syncButtonTextStart", IDS_SYNC_SETUP_BUTTON_LABEL },
    398     { "timezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION },
    399     { "use24HourClock", IDS_OPTIONS_SETTINGS_USE_24HOUR_CLOCK_DESCRIPTION },
    400 #else
    401     { "cloudPrintConnectorEnabledManageButton",
    402       IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_ENABLED_MANAGE_BUTTON},
    403     { "cloudPrintConnectorEnablingButton",
    404       IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_ENABLING_BUTTON },
    405     { "proxiesConfigureButton", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON },
    406 #endif
    407 #if defined(OS_CHROMEOS) && defined(USE_ASH)
    408     { "setWallpaper", IDS_SET_WALLPAPER_BUTTON },
    409 #endif
    410     { "advancedSectionTitleSystem",
    411       IDS_OPTIONS_ADVANCED_SECTION_TITLE_SYSTEM },
    412 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
    413     { "backgroundModeCheckbox", IDS_OPTIONS_SYSTEM_ENABLE_BACKGROUND_MODE },
    414 #endif
    415 #if !defined(OS_CHROMEOS)
    416     { "gpuModeCheckbox",
    417       IDS_OPTIONS_SYSTEM_ENABLE_HARDWARE_ACCELERATION_MODE },
    418     { "gpuModeResetRestart",
    419       IDS_OPTIONS_SYSTEM_ENABLE_HARDWARE_ACCELERATION_MODE_RESTART },
    420     // Strings with product-name substitutions.
    421     { "syncOverview", IDS_SYNC_OVERVIEW, IDS_PRODUCT_NAME },
    422     { "syncButtonTextStart", IDS_SYNC_SETUP_BUTTON_LABEL },
    423 #endif
    424     { "syncButtonTextSignIn", IDS_SYNC_START_SYNC_BUTTON_LABEL,
    425       IDS_SHORT_PRODUCT_NAME },
    426     { "profilesSingleUser", IDS_PROFILES_SINGLE_USER_MESSAGE,
    427       IDS_PRODUCT_NAME },
    428     { "defaultBrowserUnknown", IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN,
    429       IDS_PRODUCT_NAME },
    430     { "defaultBrowserUseAsDefault", IDS_OPTIONS_DEFAULTBROWSER_USEASDEFAULT,
    431       IDS_PRODUCT_NAME },
    432     { "autoLaunchText", IDS_AUTOLAUNCH_TEXT, IDS_PRODUCT_NAME },
    433 #if defined(OS_CHROMEOS)
    434     { "factoryResetDescription", IDS_OPTIONS_FACTORY_RESET_DESCRIPTION,
    435       IDS_SHORT_PRODUCT_NAME },
    436 #endif
    437     { "languageSectionLabel", IDS_OPTIONS_ADVANCED_LANGUAGE_LABEL,
    438       IDS_SHORT_PRODUCT_NAME },
    439   };
    440 
    441 #if defined(ENABLE_SETTINGS_APP)
    442   static OptionsStringResource app_resources[] = {
    443     { "syncOverview", IDS_SETTINGS_APP_SYNC_OVERVIEW },
    444     { "syncButtonTextStart", IDS_SYNC_START_SYNC_BUTTON_LABEL,
    445       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
    446     { "profilesSingleUser", IDS_PROFILES_SINGLE_USER_MESSAGE,
    447       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
    448     { "languageSectionLabel", IDS_OPTIONS_ADVANCED_LANGUAGE_LABEL,
    449       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
    450     { "proxiesLabelSystem", IDS_OPTIONS_SYSTEM_PROXIES_LABEL,
    451       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
    452   };
    453   DictionaryValue* app_values = NULL;
    454   CHECK(values->GetDictionary(kSettingsAppKey, &app_values));
    455   RegisterStrings(app_values, app_resources, arraysize(app_resources));
    456 #endif
    457 
    458   RegisterStrings(values, resources, arraysize(resources));
    459   RegisterTitle(values, "doNotTrackConfirmOverlay",
    460                 IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_TITLE);
    461   RegisterTitle(values, "spellingConfirmOverlay",
    462                 IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE);
    463 #if defined(ENABLE_FULL_PRINTING)
    464   RegisterCloudPrintValues(values);
    465 #endif
    466 
    467   values->SetString("syncLearnMoreURL", chrome::kSyncLearnMoreURL);
    468   string16 omnibox_url = ASCIIToUTF16(chrome::kOmniboxLearnMoreURL);
    469   values->SetString(
    470       "defaultSearchGroupLabel",
    471       l10n_util::GetStringFUTF16(IDS_SEARCH_PREF_EXPLANATION, omnibox_url));
    472 
    473 #if defined(OS_CHROMEOS)
    474   const chromeos::User* user = chromeos::UserManager::Get()->GetLoggedInUser();
    475   values->SetString("username", user ? user->email() : std::string());
    476 #endif
    477 
    478   // Pass along sync status early so it will be available during page init.
    479   values->Set("syncData", GetSyncStateDictionary().release());
    480 
    481   values->SetString("privacyLearnMoreURL", chrome::kPrivacyLearnMoreURL);
    482   values->SetString("doNotTrackLearnMoreURL", chrome::kDoNotTrackLearnMoreURL);
    483 
    484 #if defined(OS_CHROMEOS)
    485   values->SetString("cloudPrintLearnMoreURL", chrome::kCloudPrintLearnMoreURL);
    486 
    487   // TODO(pastarmovj): replace this with a call to the CrosSettings list
    488   // handling functionality to come.
    489   values->Set("timezoneList", GetTimezoneList().release());
    490 
    491   values->SetString("accessibilityLearnMoreURL",
    492                     chrome::kChromeAccessibilityHelpURL);
    493 
    494   // Creates magnifierList.
    495   scoped_ptr<base::ListValue> magnifier_list(new base::ListValue);
    496 
    497   scoped_ptr<base::ListValue> option_full(new base::ListValue);
    498   option_full->AppendInteger(ash::MAGNIFIER_FULL);
    499   option_full->AppendString(l10n_util::GetStringUTF16(
    500       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_FULL));
    501   magnifier_list->Append(option_full.release());
    502 
    503   scoped_ptr<base::ListValue> option_partial(new base::ListValue);
    504   option_partial->AppendInteger(ash::MAGNIFIER_PARTIAL);
    505   option_partial->Append(new base::StringValue(l10n_util::GetStringUTF16(
    506       IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_PARTIAL)));
    507   magnifier_list->Append(option_partial.release());
    508 
    509   values->Set("magnifierList", magnifier_list.release());
    510 
    511   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    512   values->SetBoolean("enableStickyKeys",
    513                      command_line.HasSwitch(switches::kEnableStickyKeys));
    514 #endif
    515 
    516 #if defined(OS_MACOSX)
    517   values->SetString("macPasswordsWarning",
    518       l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MAC_WARNING));
    519   values->SetBoolean("multiple_profiles",
    520       g_browser_process->profile_manager()->GetNumberOfProfiles() > 1);
    521 #endif
    522 
    523   if (ShouldShowMultiProfilesUserList(GetDesktopType()))
    524     values->Set("profilesInfo", GetProfilesInfoList().release());
    525 
    526   values->SetBoolean("profileIsManaged",
    527                      Profile::FromWebUI(web_ui())->IsManaged());
    528 
    529 #if !defined(OS_CHROMEOS)
    530   values->SetBoolean(
    531       "gpuEnabledAtStart",
    532       g_browser_process->gpu_mode_manager()->initial_gpu_mode_pref());
    533 #endif
    534 
    535   bool finch_allows_button =
    536       base::FieldTrialList::FindFullName(kProfileResetTrialName) ==
    537       kProfileResetTrialEnableGroupName;
    538   values->SetBoolean("enableResetProfileSettingsSection",
    539                      finch_allows_button ||
    540                      CommandLine::ForCurrentProcess()->HasSwitch(
    541                          switches::kEnableResetProfileSettings));
    542 }
    543 
    544 #if defined(ENABLE_FULL_PRINTING)
    545 void BrowserOptionsHandler::RegisterCloudPrintValues(DictionaryValue* values) {
    546 #if defined(OS_CHROMEOS)
    547   values->SetString("cloudPrintChromeosOptionLabel",
    548       l10n_util::GetStringFUTF16(
    549       IDS_CLOUD_PRINT_CHROMEOS_OPTION_LABEL,
    550       l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)));
    551   values->SetString("cloudPrintChromeosOptionButton",
    552       l10n_util::GetStringFUTF16(
    553       IDS_CLOUD_PRINT_CHROMEOS_OPTION_BUTTON,
    554       l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)));
    555 #else
    556   values->SetString("cloudPrintConnectorDisabledLabel",
    557       l10n_util::GetStringFUTF16(
    558       IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_DISABLED_LABEL,
    559       l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)));
    560   values->SetString("cloudPrintConnectorDisabledButton",
    561       l10n_util::GetStringUTF16(
    562       IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_DISABLED_BUTTON));
    563   values->SetString("cloudPrintConnectorEnabledButton",
    564       l10n_util::GetStringUTF16(
    565       IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_ENABLED_BUTTON));
    566 #endif
    567 }
    568 #endif  // defined(ENABLE_FULL_PRINTING)
    569 
    570 void BrowserOptionsHandler::RegisterMessages() {
    571   web_ui()->RegisterMessageCallback(
    572       "becomeDefaultBrowser",
    573       base::Bind(&BrowserOptionsHandler::BecomeDefaultBrowser,
    574                  base::Unretained(this)));
    575   web_ui()->RegisterMessageCallback(
    576       "setDefaultSearchEngine",
    577       base::Bind(&BrowserOptionsHandler::SetDefaultSearchEngine,
    578                  base::Unretained(this)));
    579   web_ui()->RegisterMessageCallback(
    580       "createProfile",
    581       base::Bind(&BrowserOptionsHandler::CreateProfile,
    582                  base::Unretained(this)));
    583   web_ui()->RegisterMessageCallback(
    584       "deleteProfile",
    585       base::Bind(&BrowserOptionsHandler::DeleteProfile,
    586                  base::Unretained(this)));
    587   web_ui()->RegisterMessageCallback(
    588       "cancelCreateProfile",
    589       base::Bind(&BrowserOptionsHandler::HandleCancelProfileCreation,
    590                  base::Unretained(this)));
    591   web_ui()->RegisterMessageCallback(
    592       "themesReset",
    593       base::Bind(&BrowserOptionsHandler::ThemesReset,
    594                  base::Unretained(this)));
    595   web_ui()->RegisterMessageCallback(
    596       "requestProfilesInfo",
    597       base::Bind(&BrowserOptionsHandler::HandleRequestProfilesInfo,
    598                  base::Unretained(this)));
    599 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
    600   web_ui()->RegisterMessageCallback(
    601       "themesSetNative",
    602       base::Bind(&BrowserOptionsHandler::ThemesSetNative,
    603                  base::Unretained(this)));
    604 #endif
    605   web_ui()->RegisterMessageCallback(
    606       "selectDownloadLocation",
    607       base::Bind(&BrowserOptionsHandler::HandleSelectDownloadLocation,
    608                  base::Unretained(this)));
    609   web_ui()->RegisterMessageCallback(
    610       "autoOpenFileTypesAction",
    611       base::Bind(&BrowserOptionsHandler::HandleAutoOpenButton,
    612                  base::Unretained(this)));
    613   web_ui()->RegisterMessageCallback(
    614       "defaultFontSizeAction",
    615       base::Bind(&BrowserOptionsHandler::HandleDefaultFontSize,
    616                  base::Unretained(this)));
    617   web_ui()->RegisterMessageCallback(
    618       "defaultZoomFactorAction",
    619       base::Bind(&BrowserOptionsHandler::HandleDefaultZoomFactor,
    620                  base::Unretained(this)));
    621 #if !defined(USE_NSS) && !defined(USE_OPENSSL)
    622   web_ui()->RegisterMessageCallback(
    623       "showManageSSLCertificates",
    624       base::Bind(&BrowserOptionsHandler::ShowManageSSLCertificates,
    625                  base::Unretained(this)));
    626 #endif
    627 #if defined(ENABLE_FULL_PRINTING)
    628   web_ui()->RegisterMessageCallback(
    629       "showCloudPrintManagePage",
    630       base::Bind(&BrowserOptionsHandler::ShowCloudPrintManagePage,
    631                  base::Unretained(this)));
    632 #endif
    633 #if defined(OS_CHROMEOS)
    634   web_ui()->RegisterMessageCallback(
    635       "openWallpaperManager",
    636       base::Bind(&BrowserOptionsHandler::HandleOpenWallpaperManager,
    637                  base::Unretained(this)));
    638   web_ui()->RegisterMessageCallback(
    639       "virtualKeyboardChange",
    640       base::Bind(&BrowserOptionsHandler::VirtualKeyboardChangeCallback,
    641                  base::Unretained(this)));
    642   web_ui()->RegisterMessageCallback(
    643       "performFactoryResetRestart",
    644       base::Bind(&BrowserOptionsHandler::PerformFactoryResetRestart,
    645                  base::Unretained(this)));
    646 #else
    647   web_ui()->RegisterMessageCallback(
    648       "restartBrowser",
    649       base::Bind(&BrowserOptionsHandler::HandleRestartBrowser,
    650                  base::Unretained(this)));
    651 #if defined(ENABLE_FULL_PRINTING)
    652   if (cloud_print_connector_ui_enabled_) {
    653     web_ui()->RegisterMessageCallback(
    654         "showCloudPrintSetupDialog",
    655         base::Bind(&BrowserOptionsHandler::ShowCloudPrintSetupDialog,
    656                    base::Unretained(this)));
    657     web_ui()->RegisterMessageCallback(
    658         "disableCloudPrintConnector",
    659         base::Bind(&BrowserOptionsHandler::HandleDisableCloudPrintConnector,
    660                    base::Unretained(this)));
    661   }
    662 #endif  // defined(ENABLE_FULL_PRINTING)
    663   web_ui()->RegisterMessageCallback(
    664       "showNetworkProxySettings",
    665       base::Bind(&BrowserOptionsHandler::ShowNetworkProxySettings,
    666                  base::Unretained(this)));
    667 #endif  // defined(OS_CHROMEOS)
    668 }
    669 
    670 void BrowserOptionsHandler::OnStateChanged() {
    671   UpdateSyncState();
    672 }
    673 
    674 void BrowserOptionsHandler::PageLoadStarted() {
    675   page_initialized_ = false;
    676 }
    677 
    678 void BrowserOptionsHandler::InitializeHandler() {
    679   Profile* profile = Profile::FromWebUI(web_ui());
    680   PrefService* prefs = profile->GetPrefs();
    681 
    682   ProfileSyncService* sync_service(
    683       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile));
    684   if (sync_service)
    685     sync_service->AddObserver(this);
    686 
    687   // Create our favicon data source.
    688   content::URLDataSource::Add(
    689       profile, new FaviconSource(profile, FaviconSource::FAVICON));
    690 
    691   default_browser_policy_.Init(
    692       prefs::kDefaultBrowserSettingEnabled,
    693       g_browser_process->local_state(),
    694       base::Bind(&BrowserOptionsHandler::UpdateDefaultBrowserState,
    695                  base::Unretained(this)));
    696 
    697   registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
    698                  content::NotificationService::AllSources());
    699 #if defined(OS_CHROMEOS)
    700   registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
    701                  content::NotificationService::AllSources());
    702 #endif
    703   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
    704                  content::Source<ThemeService>(
    705                      ThemeServiceFactory::GetForProfile(profile)));
    706   registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
    707                  content::Source<Profile>(profile));
    708   registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
    709                  content::Source<Profile>(profile));
    710   AddTemplateUrlServiceObserver();
    711 
    712 #if defined(OS_WIN)
    713   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    714   if (!command_line.HasSwitch(switches::kChromeFrame) &&
    715       !command_line.HasSwitch(switches::kUserDataDir)) {
    716     BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
    717         base::Bind(&BrowserOptionsHandler::CheckAutoLaunch,
    718                    weak_ptr_factory_.GetWeakPtr(),
    719                    profile->GetPath()));
    720   }
    721 #endif
    722 
    723 #if defined(ENABLE_FULL_PRINTING) && !defined(OS_CHROMEOS)
    724   base::Closure cloud_print_callback = base::Bind(
    725       &BrowserOptionsHandler::OnCloudPrintPrefsChanged, base::Unretained(this));
    726   cloud_print_connector_email_.Init(
    727       prefs::kCloudPrintEmail, prefs, cloud_print_callback);
    728   cloud_print_connector_enabled_.Init(
    729       prefs::kCloudPrintProxyEnabled, prefs, cloud_print_callback);
    730 #endif
    731 
    732   auto_open_files_.Init(
    733       prefs::kDownloadExtensionsToOpen, prefs,
    734       base::Bind(&BrowserOptionsHandler::SetupAutoOpenFileTypes,
    735                  base::Unretained(this)));
    736   default_zoom_level_.Init(
    737       prefs::kDefaultZoomLevel, prefs,
    738       base::Bind(&BrowserOptionsHandler::SetupPageZoomSelector,
    739                  base::Unretained(this)));
    740   profile_pref_registrar_.Init(prefs);
    741   profile_pref_registrar_.Add(
    742       prefs::kWebKitDefaultFontSize,
    743       base::Bind(&BrowserOptionsHandler::SetupFontSizeSelector,
    744                  base::Unretained(this)));
    745   profile_pref_registrar_.Add(
    746       prefs::kWebKitDefaultFixedFontSize,
    747       base::Bind(&BrowserOptionsHandler::SetupFontSizeSelector,
    748                  base::Unretained(this)));
    749   profile_pref_registrar_.Add(
    750       prefs::kSigninAllowed,
    751       base::Bind(&BrowserOptionsHandler::OnSigninAllowedPrefChange,
    752                  base::Unretained(this)));
    753 
    754 #if !defined(OS_CHROMEOS)
    755   profile_pref_registrar_.Add(
    756       prefs::kProxy,
    757       base::Bind(&BrowserOptionsHandler::SetupProxySettingsSection,
    758                  base::Unretained(this)));
    759 #endif  // !defined(OS_CHROMEOS)
    760 }
    761 
    762 void BrowserOptionsHandler::InitializePage() {
    763   page_initialized_ = true;
    764 
    765   OnTemplateURLServiceChanged();
    766 
    767   ObserveThemeChanged();
    768   OnStateChanged();
    769   UpdateDefaultBrowserState();
    770 
    771   SetupMetricsReportingSettingVisibility();
    772   SetupPasswordGenerationSettingVisibility();
    773   SetupFontSizeSelector();
    774   SetupPageZoomSelector();
    775   SetupAutoOpenFileTypes();
    776   SetupProxySettingsSection();
    777 
    778 #if defined(ENABLE_FULL_PRINTING) && !defined(OS_CHROMEOS)
    779   if (cloud_print_connector_ui_enabled_) {
    780     SetupCloudPrintConnectorSection();
    781     RefreshCloudPrintStatusFromService();
    782   } else {
    783     RemoveCloudPrintConnectorSection();
    784   }
    785 #endif
    786 
    787 #if defined(OS_CHROMEOS)
    788   SetupAccessibilityFeatures();
    789   if (!g_browser_process->browser_policy_connector()->IsEnterpriseManaged() &&
    790       !chromeos::UserManager::Get()->IsLoggedInAsGuest() &&
    791       !chromeos::UserManager::Get()->IsLoggedInAsLocallyManagedUser()) {
    792     web_ui()->CallJavascriptFunction(
    793         "BrowserOptions.enableFactoryResetSection");
    794   }
    795 #endif
    796 }
    797 
    798 // static
    799 void BrowserOptionsHandler::CheckAutoLaunch(
    800     base::WeakPtr<BrowserOptionsHandler> weak_this,
    801     const base::FilePath& profile_path) {
    802 #if defined(OS_WIN)
    803   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    804 
    805   // Auto-launch is not supported for secondary profiles yet.
    806   if (profile_path.BaseName().value() != ASCIIToUTF16(chrome::kInitialProfile))
    807     return;
    808 
    809   // Pass in weak pointer to this to avoid race if BrowserOptionsHandler is
    810   // deleted.
    811   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
    812       base::Bind(&BrowserOptionsHandler::CheckAutoLaunchCallback,
    813                  weak_this,
    814                  auto_launch_trial::IsInAutoLaunchGroup(),
    815                  auto_launch_util::AutoStartRequested(
    816                      profile_path.BaseName().value(),
    817                      true,  // Window requested.
    818                      base::FilePath())));
    819 #endif
    820 }
    821 
    822 void BrowserOptionsHandler::CheckAutoLaunchCallback(
    823     bool is_in_auto_launch_group,
    824     bool will_launch_at_login) {
    825 #if defined(OS_WIN)
    826   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    827 
    828   if (is_in_auto_launch_group) {
    829     web_ui()->RegisterMessageCallback("toggleAutoLaunch",
    830         base::Bind(&BrowserOptionsHandler::ToggleAutoLaunch,
    831         base::Unretained(this)));
    832 
    833     base::FundamentalValue enabled(will_launch_at_login);
    834     web_ui()->CallJavascriptFunction("BrowserOptions.updateAutoLaunchState",
    835                                      enabled);
    836   }
    837 #endif
    838 }
    839 
    840 void BrowserOptionsHandler::UpdateDefaultBrowserState() {
    841   // Check for side-by-side first.
    842   if (ShellIntegration::CanSetAsDefaultBrowser() ==
    843           ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
    844     SetDefaultBrowserUIString(IDS_OPTIONS_DEFAULTBROWSER_SXS);
    845     return;
    846   }
    847 
    848 #if defined(OS_MACOSX)
    849   ShellIntegration::DefaultWebClientState state =
    850       ShellIntegration::GetDefaultBrowser();
    851   int status_string_id;
    852   if (state == ShellIntegration::IS_DEFAULT)
    853     status_string_id = IDS_OPTIONS_DEFAULTBROWSER_DEFAULT;
    854   else if (state == ShellIntegration::NOT_DEFAULT)
    855     status_string_id = IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT;
    856   else
    857     status_string_id = IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN;
    858 
    859   SetDefaultBrowserUIString(status_string_id);
    860 #else
    861   default_browser_worker_->StartCheckIsDefault();
    862 #endif
    863 }
    864 
    865 void BrowserOptionsHandler::BecomeDefaultBrowser(const ListValue* args) {
    866   // If the default browser setting is managed then we should not be able to
    867   // call this function.
    868   if (default_browser_policy_.IsManaged())
    869     return;
    870 
    871   content::RecordAction(UserMetricsAction("Options_SetAsDefaultBrowser"));
    872 #if defined(OS_MACOSX)
    873   if (ShellIntegration::SetAsDefaultBrowser())
    874     UpdateDefaultBrowserState();
    875 #else
    876   default_browser_worker_->StartSetAsDefault();
    877   // Callback takes care of updating UI.
    878 #endif
    879 
    880   // If the user attempted to make Chrome the default browser, then he/she
    881   // arguably wants to be notified when that changes.
    882   PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
    883   prefs->SetBoolean(prefs::kCheckDefaultBrowser, true);
    884 }
    885 
    886 int BrowserOptionsHandler::StatusStringIdForState(
    887     ShellIntegration::DefaultWebClientState state) {
    888   if (state == ShellIntegration::IS_DEFAULT)
    889     return IDS_OPTIONS_DEFAULTBROWSER_DEFAULT;
    890   if (state == ShellIntegration::NOT_DEFAULT)
    891     return IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT;
    892   return IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN;
    893 }
    894 
    895 void BrowserOptionsHandler::SetDefaultWebClientUIState(
    896     ShellIntegration::DefaultWebClientUIState state) {
    897   int status_string_id;
    898   if (state == ShellIntegration::STATE_IS_DEFAULT)
    899     status_string_id = IDS_OPTIONS_DEFAULTBROWSER_DEFAULT;
    900   else if (state == ShellIntegration::STATE_NOT_DEFAULT)
    901     status_string_id = IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT;
    902   else if (state == ShellIntegration::STATE_UNKNOWN)
    903     status_string_id = IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN;
    904   else
    905     return;  // Still processing.
    906 
    907   SetDefaultBrowserUIString(status_string_id);
    908 }
    909 
    910 bool BrowserOptionsHandler::IsInteractiveSetDefaultPermitted() {
    911   return true;  // This is UI so we can allow it.
    912 }
    913 
    914 void BrowserOptionsHandler::SetDefaultBrowserUIString(int status_string_id) {
    915   base::StringValue status_string(
    916       l10n_util::GetStringFUTF16(status_string_id,
    917                                  l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
    918 
    919   base::FundamentalValue is_default(
    920       status_string_id == IDS_OPTIONS_DEFAULTBROWSER_DEFAULT);
    921 
    922   base::FundamentalValue can_be_default(
    923       !default_browser_policy_.IsManaged() &&
    924       (status_string_id == IDS_OPTIONS_DEFAULTBROWSER_DEFAULT ||
    925        status_string_id == IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT));
    926 
    927   web_ui()->CallJavascriptFunction(
    928       "BrowserOptions.updateDefaultBrowserState",
    929       status_string, is_default, can_be_default);
    930 }
    931 
    932 void BrowserOptionsHandler::OnTemplateURLServiceChanged() {
    933   if (!template_url_service_ || !template_url_service_->loaded())
    934     return;
    935 
    936   const TemplateURL* default_url =
    937       template_url_service_->GetDefaultSearchProvider();
    938 
    939   int default_index = -1;
    940   ListValue search_engines;
    941   TemplateURLService::TemplateURLVector model_urls(
    942       template_url_service_->GetTemplateURLs());
    943   for (size_t i = 0; i < model_urls.size(); ++i) {
    944     if (!model_urls[i]->ShowInDefaultList())
    945       continue;
    946 
    947     DictionaryValue* entry = new DictionaryValue();
    948     entry->SetString("name", model_urls[i]->short_name());
    949     entry->SetInteger("index", i);
    950     search_engines.Append(entry);
    951     if (model_urls[i] == default_url)
    952       default_index = i;
    953   }
    954 
    955   web_ui()->CallJavascriptFunction(
    956       "BrowserOptions.updateSearchEngines",
    957       search_engines,
    958       base::FundamentalValue(default_index),
    959       base::FundamentalValue(
    960           template_url_service_->is_default_search_managed()));
    961 }
    962 
    963 void BrowserOptionsHandler::SetDefaultSearchEngine(const ListValue* args) {
    964   int selected_index = -1;
    965   if (!ExtractIntegerValue(args, &selected_index)) {
    966     NOTREACHED();
    967     return;
    968   }
    969 
    970   TemplateURLService::TemplateURLVector model_urls(
    971       template_url_service_->GetTemplateURLs());
    972   if (selected_index >= 0 &&
    973       selected_index < static_cast<int>(model_urls.size()))
    974     template_url_service_->SetDefaultSearchProvider(model_urls[selected_index]);
    975 
    976   content::RecordAction(UserMetricsAction("Options_SearchEngineChanged"));
    977 }
    978 
    979 void BrowserOptionsHandler::AddTemplateUrlServiceObserver() {
    980   template_url_service_ =
    981       TemplateURLServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
    982   if (template_url_service_) {
    983     template_url_service_->Load();
    984     template_url_service_->AddObserver(this);
    985   }
    986 }
    987 
    988 void BrowserOptionsHandler::Observe(
    989     int type,
    990     const content::NotificationSource& source,
    991     const content::NotificationDetails& details) {
    992   // Notifications are used to update the UI dynamically when settings change in
    993   // the background. If the UI is currently being loaded, no dynamic updates are
    994   // possible (as the DOM and JS are not fully loaded) or necessary (as
    995   // InitializePage() will update the UI at the end of the load).
    996   if (!page_initialized_)
    997     return;
    998 
    999   switch (type) {
   1000     case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
   1001       ObserveThemeChanged();
   1002       break;
   1003 #if defined(OS_CHROMEOS)
   1004     case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED:
   1005       UpdateAccountPicture();
   1006       break;
   1007 #endif
   1008     case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED:
   1009       // If the browser shuts down during supervised-profile creation, deleting
   1010       // the unregistered supervised-user profile triggers this notification,
   1011       // but the RenderViewHost the profile info would be sent to has already
   1012       // been destroyed.
   1013       if (!web_ui()->GetWebContents()->GetRenderViewHost())
   1014         return;
   1015       SendProfilesInfo();
   1016       break;
   1017     case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL:
   1018     case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
   1019       // Update our sync/signin status display.
   1020       OnStateChanged();
   1021       break;
   1022     default:
   1023       NOTREACHED();
   1024   }
   1025 }
   1026 
   1027 #if defined(ENABLE_FULL_PRINTING) && !defined(OS_CHROMEOS)
   1028 void BrowserOptionsHandler::OnCloudPrintPrefsChanged() {
   1029   if (cloud_print_connector_ui_enabled_)
   1030     SetupCloudPrintConnectorSection();
   1031 }
   1032 #endif
   1033 
   1034 void BrowserOptionsHandler::ToggleAutoLaunch(const ListValue* args) {
   1035 #if defined(OS_WIN)
   1036   if (!auto_launch_trial::IsInAutoLaunchGroup())
   1037     return;
   1038 
   1039   bool enable;
   1040   CHECK_EQ(args->GetSize(), 1U);
   1041   CHECK(args->GetBoolean(0, &enable));
   1042 
   1043   Profile* profile = Profile::FromWebUI(web_ui());
   1044   content::BrowserThread::PostTask(
   1045       content::BrowserThread::FILE, FROM_HERE,
   1046       enable ?
   1047           base::Bind(&auto_launch_util::EnableForegroundStartAtLogin,
   1048                      profile->GetPath().BaseName().value(), base::FilePath()) :
   1049           base::Bind(&auto_launch_util::DisableForegroundStartAtLogin,
   1050                       profile->GetPath().BaseName().value()));
   1051 #endif  // OS_WIN
   1052 }
   1053 
   1054 scoped_ptr<ListValue> BrowserOptionsHandler::GetProfilesInfoList() {
   1055   ProfileInfoCache& cache =
   1056       g_browser_process->profile_manager()->GetProfileInfoCache();
   1057   scoped_ptr<ListValue> profile_info_list(new ListValue);
   1058   base::FilePath current_profile_path =
   1059       web_ui()->GetWebContents()->GetBrowserContext()->GetPath();
   1060 
   1061   for (size_t i = 0, e = cache.GetNumberOfProfiles(); i < e; ++i) {
   1062     DictionaryValue* profile_value = new DictionaryValue();
   1063     profile_value->SetString("name", cache.GetNameOfProfileAtIndex(i));
   1064     base::FilePath profile_path = cache.GetPathOfProfileAtIndex(i);
   1065     profile_value->Set("filePath", base::CreateFilePathValue(profile_path));
   1066     profile_value->SetBoolean("isCurrentProfile",
   1067                               profile_path == current_profile_path);
   1068     profile_value->SetBoolean("isManaged", cache.ProfileIsManagedAtIndex(i));
   1069 
   1070     bool is_gaia_picture =
   1071         cache.IsUsingGAIAPictureOfProfileAtIndex(i) &&
   1072         cache.GetGAIAPictureOfProfileAtIndex(i);
   1073     if (is_gaia_picture) {
   1074       gfx::Image icon = profiles::GetAvatarIconForWebUI(
   1075           cache.GetAvatarIconOfProfileAtIndex(i), true);
   1076       profile_value->SetString("iconURL",
   1077           webui::GetBitmapDataUrl(icon.AsBitmap()));
   1078     } else {
   1079       size_t icon_index = cache.GetAvatarIconIndexOfProfileAtIndex(i);
   1080       profile_value->SetString("iconURL",
   1081                                cache.GetDefaultAvatarIconUrl(icon_index));
   1082     }
   1083 
   1084     profile_info_list->Append(profile_value);
   1085   }
   1086 
   1087   return profile_info_list.Pass();
   1088 }
   1089 
   1090 void BrowserOptionsHandler::SendProfilesInfo() {
   1091   if (!ShouldShowMultiProfilesUserList(GetDesktopType()))
   1092     return;
   1093   web_ui()->CallJavascriptFunction("BrowserOptions.setProfilesInfo",
   1094                                    *GetProfilesInfoList());
   1095 }
   1096 
   1097 chrome::HostDesktopType BrowserOptionsHandler::GetDesktopType() {
   1098   Browser* browser =
   1099       chrome::FindBrowserWithWebContents(web_ui()->GetWebContents());
   1100   chrome::HostDesktopType desktop_type = chrome::HOST_DESKTOP_TYPE_NATIVE;
   1101   if (browser)
   1102     desktop_type = browser->host_desktop_type();
   1103   return desktop_type;
   1104 }
   1105 
   1106 void BrowserOptionsHandler::CreateProfile(const ListValue* args) {
   1107   // This handler could have been called in managed mode, for example because
   1108   // the user fiddled with the web inspector. Silently return in this case.
   1109   Profile* current_profile = Profile::FromWebUI(web_ui());
   1110   if (current_profile->IsManaged())
   1111     return;
   1112 
   1113   if (!profiles::IsMultipleProfilesEnabled())
   1114     return;
   1115 
   1116   DCHECK(profile_path_being_created_.empty());
   1117   profile_creation_start_time_ = base::TimeTicks::Now();
   1118 
   1119   string16 name;
   1120   string16 icon;
   1121   std::string managed_user_id;
   1122   bool create_shortcut = false;
   1123   bool managed_user = false;
   1124   if (args->GetString(0, &name) && args->GetString(1, &icon)) {
   1125     if (args->GetBoolean(2, &create_shortcut)) {
   1126       bool success = args->GetBoolean(3, &managed_user);
   1127       DCHECK(success);
   1128       success = args->GetString(4, &managed_user_id);
   1129       DCHECK(success);
   1130     }
   1131   }
   1132 
   1133   std::vector<ProfileManager::CreateCallback> callbacks;
   1134   if (create_shortcut)
   1135     callbacks.push_back(base::Bind(&CreateDesktopShortcutForProfile));
   1136 
   1137   ProfileManager::CreateCallback show_user_feedback =
   1138       base::Bind(&BrowserOptionsHandler::ShowProfileCreationFeedback,
   1139                  weak_ptr_factory_.GetWeakPtr(), GetDesktopType(),
   1140                  managed_user);
   1141 
   1142   if (managed_user && ManagedUserService::AreManagedUsersEnabled()) {
   1143     if (!IsValidExistingManagedUserId(managed_user_id))
   1144       return;
   1145 
   1146     if (managed_user_id.empty()) {
   1147       managed_user_id =
   1148           ManagedUserRegistrationUtility::GenerateNewManagedUserId();
   1149     }
   1150     callbacks.push_back(
   1151         base::Bind(&BrowserOptionsHandler::RegisterManagedUser,
   1152                    weak_ptr_factory_.GetWeakPtr(),
   1153                    show_user_feedback,
   1154                    managed_user_id));
   1155   } else {
   1156     callbacks.push_back(show_user_feedback);
   1157   }
   1158 
   1159   ProfileMetrics::LogProfileAddNewUser(ProfileMetrics::ADD_NEW_USER_DIALOG);
   1160 
   1161   profile_path_being_created_ = ProfileManager::CreateMultiProfileAsync(
   1162       name, icon, base::Bind(&RunProfileCreationCallbacks, callbacks),
   1163       managed_user_id);
   1164 }
   1165 
   1166 void BrowserOptionsHandler::RegisterManagedUser(
   1167     const ProfileManager::CreateCallback& callback,
   1168     const std::string& managed_user_id,
   1169     Profile* new_profile,
   1170     Profile::CreateStatus status) {
   1171   DCHECK(profile_path_being_created_ == new_profile->GetPath());
   1172   if (status != Profile::CREATE_STATUS_INITIALIZED)
   1173     return;
   1174 
   1175   ManagedUserService* managed_user_service =
   1176       ManagedUserServiceFactory::GetForProfile(new_profile);
   1177 
   1178   // Register the managed user using the profile of the custodian.
   1179   managed_user_registration_utility_ =
   1180       ManagedUserRegistrationUtility::Create(Profile::FromWebUI(web_ui()));
   1181   managed_user_service->RegisterAndInitSync(
   1182       managed_user_registration_utility_.get(),
   1183       Profile::FromWebUI(web_ui()),
   1184       managed_user_id,
   1185       callback);
   1186 }
   1187 
   1188 void BrowserOptionsHandler::RecordProfileCreationMetrics(
   1189     Profile::CreateStatus status) {
   1190   UMA_HISTOGRAM_ENUMERATION("Profile.CreateResult",
   1191                             status,
   1192                             Profile::MAX_CREATE_STATUS);
   1193   UMA_HISTOGRAM_MEDIUM_TIMES(
   1194       "Profile.CreateTimeNoTimeout",
   1195       base::TimeTicks::Now() - profile_creation_start_time_);
   1196 }
   1197 
   1198 void BrowserOptionsHandler::ShowProfileCreationFeedback(
   1199     chrome::HostDesktopType desktop_type,
   1200     bool is_managed,
   1201     Profile* profile,
   1202     Profile::CreateStatus status) {
   1203   DCHECK(profile_path_being_created_ == profile->GetPath());
   1204   if (status != Profile::CREATE_STATUS_CREATED)
   1205     RecordProfileCreationMetrics(status);
   1206 
   1207   switch (status) {
   1208     case Profile::CREATE_STATUS_LOCAL_FAIL: {
   1209       profile_path_being_created_.clear();
   1210       web_ui()->CallJavascriptFunction(
   1211           "BrowserOptions.showCreateProfileLocalError");
   1212       DeleteProfileAtPath(profile->GetPath());
   1213       break;
   1214     }
   1215     case Profile::CREATE_STATUS_REMOTE_FAIL: {
   1216       profile_path_being_created_.clear();
   1217       web_ui()->CallJavascriptFunction(
   1218           "BrowserOptions.showCreateProfileRemoteError");
   1219       DeleteProfileAtPath(profile->GetPath());
   1220       break;
   1221     }
   1222     case Profile::CREATE_STATUS_CREATED: {
   1223       // Do nothing for an intermediate status.
   1224       break;
   1225     }
   1226     case Profile::CREATE_STATUS_INITIALIZED: {
   1227       profile_path_being_created_.clear();
   1228       DictionaryValue dict;
   1229       dict.SetString("name",
   1230                      profile->GetPrefs()->GetString(prefs::kProfileName));
   1231       dict.Set("filePath", base::CreateFilePathValue(profile->GetPath()));
   1232       dict.SetBoolean("isManaged", is_managed);
   1233       web_ui()->CallJavascriptFunction(
   1234           "BrowserOptions.showCreateProfileSuccess", dict);
   1235 
   1236       // If the new profile is a managed user, instead of opening a new window
   1237       // right away, a confirmation overlay will be shown from the creation
   1238       // dialog.
   1239       if (!is_managed) {
   1240         // Opening the new window must be the last action, after all callbacks
   1241         // have been run, to give them a chance to initialize the profile.
   1242         OpenNewWindowForProfile(desktop_type,
   1243                                 profile,
   1244                                 Profile::CREATE_STATUS_INITIALIZED);
   1245       }
   1246       break;
   1247     }
   1248     // User-initiated cancellation is handled in CancelProfileRegistration and
   1249     // does not call this callback.
   1250     case Profile::CREATE_STATUS_CANCELED:
   1251     case Profile::MAX_CREATE_STATUS: {
   1252       NOTREACHED();
   1253       break;
   1254     }
   1255   }
   1256 }
   1257 
   1258 void BrowserOptionsHandler::DeleteProfile(const ListValue* args) {
   1259   DCHECK(args);
   1260   const Value* file_path_value;
   1261   if (!args->Get(0, &file_path_value))
   1262     return;
   1263 
   1264   base::FilePath file_path;
   1265   if (!base::GetValueAsFilePath(*file_path_value, &file_path))
   1266     return;
   1267   DeleteProfileAtPath(file_path);
   1268 }
   1269 
   1270 void BrowserOptionsHandler::DeleteProfileAtPath(base::FilePath file_path) {
   1271   // This handler could have been called in managed mode, for example because
   1272   // the user fiddled with the web inspector. Silently return in this case.
   1273   if (Profile::FromWebUI(web_ui())->IsManaged())
   1274     return;
   1275 
   1276   if (!profiles::IsMultipleProfilesEnabled())
   1277     return;
   1278 
   1279   ProfileMetrics::LogProfileDeleteUser(ProfileMetrics::PROFILE_DELETED);
   1280 
   1281   g_browser_process->profile_manager()->ScheduleProfileForDeletion(
   1282       file_path,
   1283       base::Bind(&OpenNewWindowForProfile, GetDesktopType()));
   1284 }
   1285 
   1286 void BrowserOptionsHandler::HandleCancelProfileCreation(const ListValue* args) {
   1287   CancelProfileRegistration(true);
   1288 }
   1289 
   1290 void BrowserOptionsHandler::CancelProfileRegistration(bool user_initiated) {
   1291   if (profile_path_being_created_.empty())
   1292     return;
   1293 
   1294   ProfileManager* manager = g_browser_process->profile_manager();
   1295   Profile* new_profile = manager->GetProfileByPath(profile_path_being_created_);
   1296   if (!new_profile)
   1297     return;
   1298 
   1299   // Non-managed user creation cannot be canceled. (Creating a non-managed
   1300   // profile shouldn't take significant time, and it can easily be deleted
   1301   // afterward.)
   1302   if (!new_profile->IsManaged())
   1303     return;
   1304 
   1305   if (user_initiated) {
   1306     UMA_HISTOGRAM_MEDIUM_TIMES(
   1307         "Profile.CreateTimeCanceledNoTimeout",
   1308         base::TimeTicks::Now() - profile_creation_start_time_);
   1309     RecordProfileCreationMetrics(Profile::CREATE_STATUS_CANCELED);
   1310   }
   1311 
   1312   DCHECK(managed_user_registration_utility_.get());
   1313   managed_user_registration_utility_.reset();
   1314 
   1315   // Cancelling registration means the callback passed into
   1316   // RegisterAndInitSync() won't be called, so the cleanup must be done here.
   1317   profile_path_being_created_.clear();
   1318   DeleteProfileAtPath(new_profile->GetPath());
   1319 }
   1320 
   1321 void BrowserOptionsHandler::ObserveThemeChanged() {
   1322   Profile* profile = Profile::FromWebUI(web_ui());
   1323   ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile);
   1324   bool is_native_theme = false;
   1325 
   1326 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   1327   bool profile_is_managed = profile->IsManaged();
   1328   is_native_theme = theme_service->UsingNativeTheme();
   1329   base::FundamentalValue native_theme_enabled(!is_native_theme &&
   1330                                               !profile_is_managed);
   1331   web_ui()->CallJavascriptFunction("BrowserOptions.setNativeThemeButtonEnabled",
   1332                                    native_theme_enabled);
   1333 #endif
   1334 
   1335   bool is_classic_theme = !is_native_theme &&
   1336                           theme_service->UsingDefaultTheme();
   1337   base::FundamentalValue enabled(!is_classic_theme);
   1338   web_ui()->CallJavascriptFunction("BrowserOptions.setThemesResetButtonEnabled",
   1339                                    enabled);
   1340 }
   1341 
   1342 void BrowserOptionsHandler::ThemesReset(const ListValue* args) {
   1343   Profile* profile = Profile::FromWebUI(web_ui());
   1344   content::RecordAction(UserMetricsAction("Options_ThemesReset"));
   1345   ThemeServiceFactory::GetForProfile(profile)->UseDefaultTheme();
   1346 }
   1347 
   1348 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   1349 void BrowserOptionsHandler::ThemesSetNative(const ListValue* args) {
   1350   content::RecordAction(UserMetricsAction("Options_GtkThemeSet"));
   1351   Profile* profile = Profile::FromWebUI(web_ui());
   1352   ThemeServiceFactory::GetForProfile(profile)->SetNativeTheme();
   1353 }
   1354 #endif
   1355 
   1356 #if defined(OS_CHROMEOS)
   1357 void BrowserOptionsHandler::UpdateAccountPicture() {
   1358   std::string email = chromeos::UserManager::Get()->GetLoggedInUser()->email();
   1359   if (!email.empty()) {
   1360     web_ui()->CallJavascriptFunction("BrowserOptions.updateAccountPicture");
   1361     base::StringValue email_value(email);
   1362     web_ui()->CallJavascriptFunction("BrowserOptions.updateAccountPicture",
   1363                                      email_value);
   1364   }
   1365 }
   1366 #endif
   1367 
   1368 scoped_ptr<DictionaryValue> BrowserOptionsHandler::GetSyncStateDictionary() {
   1369   scoped_ptr<DictionaryValue> sync_status(new DictionaryValue);
   1370   Profile* profile = Profile::FromWebUI(web_ui());
   1371   if (profile->IsManaged()) {
   1372     sync_status->SetBoolean("supervisedUser", true);
   1373     sync_status->SetBoolean("signinAllowed", false);
   1374     return sync_status.Pass();
   1375   }
   1376   if (profile->IsGuestSession()) {
   1377     // Cannot display signin status when running in guest mode on chromeos
   1378     // because there is no SigninManager.
   1379     sync_status->SetBoolean("signinAllowed", false);
   1380     return sync_status.Pass();
   1381   }
   1382   sync_status->SetBoolean("supervisedUser", false);
   1383 
   1384   bool signout_prohibited = false;
   1385 #if !defined(OS_CHROMEOS)
   1386   // Signout is not allowed if the user has policy (crbug.com/172204).
   1387   signout_prohibited =
   1388       SigninManagerFactory::GetForProfile(profile)->IsSignoutProhibited();
   1389 #endif
   1390 
   1391   ProfileSyncService* service =
   1392       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
   1393   SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile);
   1394   DCHECK(signin);
   1395   sync_status->SetBoolean("signoutAllowed", !signout_prohibited);
   1396   sync_status->SetBoolean("signinAllowed", signin->IsSigninAllowed());
   1397   sync_status->SetBoolean("syncSystemEnabled", !!service);
   1398   sync_status->SetBoolean("setupCompleted",
   1399                           service && service->HasSyncSetupCompleted());
   1400   sync_status->SetBoolean("setupInProgress",
   1401       service && !service->IsManaged() && service->FirstSetupInProgress());
   1402 
   1403   string16 status_label;
   1404   string16 link_label;
   1405   bool status_has_error = sync_ui_util::GetStatusLabels(
   1406       service, *signin, sync_ui_util::WITH_HTML, &status_label, &link_label) ==
   1407           sync_ui_util::SYNC_ERROR;
   1408   sync_status->SetString("statusText", status_label);
   1409   sync_status->SetString("actionLinkText", link_label);
   1410   sync_status->SetBoolean("hasError", status_has_error);
   1411 
   1412   sync_status->SetBoolean("managed", service && service->IsManaged());
   1413   sync_status->SetBoolean("signedIn",
   1414                           !signin->GetAuthenticatedUsername().empty());
   1415   sync_status->SetBoolean("hasUnrecoverableError",
   1416                           service && service->HasUnrecoverableError());
   1417   sync_status->SetBoolean(
   1418       "autoLoginVisible",
   1419       CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAutologin) &&
   1420       service && service->IsSyncEnabledAndLoggedIn() &&
   1421       service->IsOAuthRefreshTokenAvailable());
   1422 
   1423   return sync_status.Pass();
   1424 }
   1425 
   1426 void BrowserOptionsHandler::HandleSelectDownloadLocation(
   1427     const ListValue* args) {
   1428   PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
   1429   select_folder_dialog_ = ui::SelectFileDialog::Create(
   1430       this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
   1431   ui::SelectFileDialog::FileTypeInfo info;
   1432   info.support_drive = true;
   1433   select_folder_dialog_->SelectFile(
   1434       ui::SelectFileDialog::SELECT_FOLDER,
   1435       l10n_util::GetStringUTF16(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE),
   1436       pref_service->GetFilePath(prefs::kDownloadDefaultDirectory),
   1437       &info,
   1438       0,
   1439       base::FilePath::StringType(),
   1440       web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
   1441       NULL);
   1442 }
   1443 
   1444 void BrowserOptionsHandler::FileSelected(const base::FilePath& path, int index,
   1445                                          void* params) {
   1446   content::RecordAction(UserMetricsAction("Options_SetDownloadDirectory"));
   1447   PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
   1448   pref_service->SetFilePath(prefs::kDownloadDefaultDirectory, path);
   1449   pref_service->SetFilePath(prefs::kSaveFileDefaultDirectory, path);
   1450 }
   1451 
   1452 #if defined(OS_CHROMEOS)
   1453 void BrowserOptionsHandler::TouchpadExists(bool exists) {
   1454   base::FundamentalValue val(exists);
   1455   web_ui()->CallJavascriptFunction("BrowserOptions.showTouchpadControls", val);
   1456 }
   1457 
   1458 void BrowserOptionsHandler::MouseExists(bool exists) {
   1459   base::FundamentalValue val(exists);
   1460   web_ui()->CallJavascriptFunction("BrowserOptions.showMouseControls", val);
   1461 }
   1462 #endif
   1463 
   1464 void BrowserOptionsHandler::UpdateSyncState() {
   1465   web_ui()->CallJavascriptFunction("BrowserOptions.updateSyncState",
   1466                                    *GetSyncStateDictionary());
   1467 }
   1468 
   1469 void BrowserOptionsHandler::OnSigninAllowedPrefChange() {
   1470   UpdateSyncState();
   1471 }
   1472 
   1473 void BrowserOptionsHandler::HandleAutoOpenButton(const ListValue* args) {
   1474   content::RecordAction(UserMetricsAction("Options_ResetAutoOpenFiles"));
   1475   DownloadManager* manager = BrowserContext::GetDownloadManager(
   1476       web_ui()->GetWebContents()->GetBrowserContext());
   1477   if (manager)
   1478     DownloadPrefs::FromDownloadManager(manager)->ResetAutoOpen();
   1479 }
   1480 
   1481 void BrowserOptionsHandler::HandleDefaultFontSize(const ListValue* args) {
   1482   int font_size;
   1483   if (ExtractIntegerValue(args, &font_size)) {
   1484     if (font_size > 0) {
   1485       PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
   1486       pref_service->SetInteger(prefs::kWebKitDefaultFontSize, font_size);
   1487       SetupFontSizeSelector();
   1488     }
   1489   }
   1490 }
   1491 
   1492 void BrowserOptionsHandler::HandleDefaultZoomFactor(const ListValue* args) {
   1493   double zoom_factor;
   1494   if (ExtractDoubleValue(args, &zoom_factor)) {
   1495     default_zoom_level_.SetValue(content::ZoomFactorToZoomLevel(zoom_factor));
   1496   }
   1497 }
   1498 
   1499 void BrowserOptionsHandler::HandleRestartBrowser(const ListValue* args) {
   1500   chrome::AttemptRestart();
   1501 }
   1502 
   1503 void BrowserOptionsHandler::HandleRequestProfilesInfo(const ListValue* args) {
   1504   SendProfilesInfo();
   1505 }
   1506 
   1507 #if !defined(OS_CHROMEOS)
   1508 void BrowserOptionsHandler::ShowNetworkProxySettings(const ListValue* args) {
   1509   content::RecordAction(UserMetricsAction("Options_ShowProxySettings"));
   1510   AdvancedOptionsUtilities::ShowNetworkProxySettings(
   1511       web_ui()->GetWebContents());
   1512 }
   1513 #endif
   1514 
   1515 #if !defined(USE_NSS) && !defined(USE_OPENSSL)
   1516 void BrowserOptionsHandler::ShowManageSSLCertificates(const ListValue* args) {
   1517   content::RecordAction(UserMetricsAction("Options_ManageSSLCertificates"));
   1518   AdvancedOptionsUtilities::ShowManageSSLCertificates(
   1519       web_ui()->GetWebContents());
   1520 }
   1521 #endif
   1522 
   1523 #if defined(ENABLE_FULL_PRINTING)
   1524 void BrowserOptionsHandler::ShowCloudPrintManagePage(const ListValue* args) {
   1525   content::RecordAction(UserMetricsAction("Options_ManageCloudPrinters"));
   1526   // Open a new tab in the current window for the management page.
   1527   Profile* profile = Profile::FromWebUI(web_ui());
   1528   OpenURLParams params(
   1529       CloudPrintURL(profile).GetCloudPrintServiceManageURL(), Referrer(),
   1530       NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false);
   1531   web_ui()->GetWebContents()->OpenURL(params);
   1532 }
   1533 
   1534 #if !defined(OS_CHROMEOS)
   1535 void BrowserOptionsHandler::ShowCloudPrintSetupDialog(const ListValue* args) {
   1536   content::RecordAction(UserMetricsAction("Options_EnableCloudPrintProxy"));
   1537   // Open the connector enable page in the current tab.
   1538   Profile* profile = Profile::FromWebUI(web_ui());
   1539   OpenURLParams params(
   1540       CloudPrintURL(profile).GetCloudPrintServiceEnableURL(
   1541           CloudPrintProxyServiceFactory::GetForProfile(profile)->proxy_id()),
   1542       Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
   1543   web_ui()->GetWebContents()->OpenURL(params);
   1544 }
   1545 
   1546 void BrowserOptionsHandler::HandleDisableCloudPrintConnector(
   1547     const ListValue* args) {
   1548   content::RecordAction(
   1549       UserMetricsAction("Options_DisableCloudPrintProxy"));
   1550   CloudPrintProxyServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()))->
   1551       DisableForUser();
   1552 }
   1553 
   1554 void BrowserOptionsHandler::RefreshCloudPrintStatusFromService() {
   1555   if (cloud_print_connector_ui_enabled_)
   1556     CloudPrintProxyServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()))->
   1557         RefreshStatusFromService();
   1558 }
   1559 
   1560 void BrowserOptionsHandler::SetupCloudPrintConnectorSection() {
   1561   Profile* profile = Profile::FromWebUI(web_ui());
   1562   if (!CloudPrintProxyServiceFactory::GetForProfile(profile)) {
   1563     cloud_print_connector_ui_enabled_ = false;
   1564     RemoveCloudPrintConnectorSection();
   1565     return;
   1566   }
   1567 
   1568   bool cloud_print_connector_allowed =
   1569       !cloud_print_connector_enabled_.IsManaged() ||
   1570       cloud_print_connector_enabled_.GetValue();
   1571   base::FundamentalValue allowed(cloud_print_connector_allowed);
   1572 
   1573   std::string email;
   1574   if (profile->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) &&
   1575       cloud_print_connector_allowed) {
   1576     email = profile->GetPrefs()->GetString(prefs::kCloudPrintEmail);
   1577   }
   1578   base::FundamentalValue disabled(email.empty());
   1579 
   1580   string16 label_str;
   1581   if (email.empty()) {
   1582     label_str = l10n_util::GetStringFUTF16(
   1583         IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_DISABLED_LABEL,
   1584         l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT));
   1585   } else {
   1586     label_str = l10n_util::GetStringFUTF16(
   1587         IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_ENABLED_LABEL,
   1588         l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT),
   1589         UTF8ToUTF16(email));
   1590   }
   1591   StringValue label(label_str);
   1592 
   1593   web_ui()->CallJavascriptFunction(
   1594       "BrowserOptions.setupCloudPrintConnectorSection", disabled, label,
   1595       allowed);
   1596 }
   1597 
   1598 void BrowserOptionsHandler::RemoveCloudPrintConnectorSection() {
   1599   web_ui()->CallJavascriptFunction(
   1600       "BrowserOptions.removeCloudPrintConnectorSection");
   1601 }
   1602 #endif  // defined(OS_CHROMEOS)
   1603 #endif  // defined(ENABLE_FULL_PRINTING)
   1604 
   1605 #if defined(OS_CHROMEOS)
   1606 void BrowserOptionsHandler::HandleOpenWallpaperManager(
   1607     const ListValue* args) {
   1608   wallpaper_manager_util::OpenWallpaperManager();
   1609 }
   1610 
   1611 void BrowserOptionsHandler::VirtualKeyboardChangeCallback(
   1612     const ListValue* args) {
   1613   bool enabled = false;
   1614   args->GetBoolean(0, &enabled);
   1615 
   1616   chromeos::accessibility::EnableVirtualKeyboard(enabled);
   1617 }
   1618 
   1619 #if defined(OS_CHROMEOS)
   1620 
   1621 void BrowserOptionsHandler::PerformFactoryResetRestart(const ListValue* args) {
   1622   if (g_browser_process->browser_policy_connector()->IsEnterpriseManaged())
   1623     return;
   1624 
   1625   PrefService* prefs = g_browser_process->local_state();
   1626   prefs->SetBoolean(prefs::kFactoryResetRequested, true);
   1627   prefs->CommitPendingWrite();
   1628 
   1629   // Perform sign out. Current chrome process will then terminate, new one will
   1630   // be launched (as if it was a restart).
   1631   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
   1632 }
   1633 
   1634 #endif
   1635 
   1636 void BrowserOptionsHandler::SetupAccessibilityFeatures() {
   1637   PrefService* pref_service = g_browser_process->local_state();
   1638   base::FundamentalValue virtual_keyboard_enabled(
   1639       pref_service->GetBoolean(prefs::kVirtualKeyboardEnabled));
   1640   web_ui()->CallJavascriptFunction(
   1641       "BrowserOptions.setVirtualKeyboardCheckboxState",
   1642       virtual_keyboard_enabled);
   1643 }
   1644 #endif
   1645 
   1646 void BrowserOptionsHandler::SetupMetricsReportingSettingVisibility() {
   1647 #if defined(GOOGLE_CHROME_BUILD) && defined(OS_CHROMEOS)
   1648   // Don't show the reporting setting if we are in the guest mode.
   1649   if (CommandLine::ForCurrentProcess()->HasSwitch(
   1650           chromeos::switches::kGuestSession)) {
   1651     base::FundamentalValue visible(false);
   1652     web_ui()->CallJavascriptFunction(
   1653         "BrowserOptions.setMetricsReportingSettingVisibility", visible);
   1654   }
   1655 #endif
   1656 }
   1657 
   1658 void BrowserOptionsHandler::SetupPasswordGenerationSettingVisibility() {
   1659   base::FundamentalValue visible(
   1660       CommandLine::ForCurrentProcess()->HasSwitch(
   1661           switches::kEnablePasswordGeneration));
   1662   web_ui()->CallJavascriptFunction(
   1663       "BrowserOptions.setPasswordGenerationSettingVisibility", visible);
   1664 }
   1665 
   1666 void BrowserOptionsHandler::SetupFontSizeSelector() {
   1667   PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
   1668   const PrefService::Preference* default_font_size =
   1669       pref_service->FindPreference(prefs::kWebKitDefaultFontSize);
   1670   const PrefService::Preference* default_fixed_font_size =
   1671       pref_service->FindPreference(prefs::kWebKitDefaultFixedFontSize);
   1672 
   1673   DictionaryValue dict;
   1674   dict.SetInteger("value",
   1675                   pref_service->GetInteger(prefs::kWebKitDefaultFontSize));
   1676 
   1677   // The font size control displays the value of the default font size, but
   1678   // setting it alters both the default font size and the default fixed font
   1679   // size. So it must be disabled when either of those prefs is not user
   1680   // modifiable.
   1681   dict.SetBoolean("disabled",
   1682       !default_font_size->IsUserModifiable() ||
   1683       !default_fixed_font_size->IsUserModifiable());
   1684 
   1685   // This is a poor man's version of CoreOptionsHandler::CreateValueForPref,
   1686   // adapted to consider two prefs. It may be better to refactor
   1687   // CreateValueForPref so it can be called from here.
   1688   if (default_font_size->IsManaged() || default_fixed_font_size->IsManaged()) {
   1689       dict.SetString("controlledBy", "policy");
   1690   } else if (default_font_size->IsExtensionControlled() ||
   1691              default_fixed_font_size->IsExtensionControlled()) {
   1692       dict.SetString("controlledBy", "extension");
   1693   }
   1694 
   1695   web_ui()->CallJavascriptFunction("BrowserOptions.setFontSize", dict);
   1696 }
   1697 
   1698 void BrowserOptionsHandler::SetupPageZoomSelector() {
   1699   PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
   1700   double default_zoom_level = pref_service->GetDouble(prefs::kDefaultZoomLevel);
   1701   double default_zoom_factor =
   1702       content::ZoomLevelToZoomFactor(default_zoom_level);
   1703 
   1704   // Generate a vector of zoom factors from an array of known presets along with
   1705   // the default factor added if necessary.
   1706   std::vector<double> zoom_factors =
   1707       chrome_page_zoom::PresetZoomFactors(default_zoom_factor);
   1708 
   1709   // Iterate through the zoom factors and and build the contents of the
   1710   // selector that will be sent to the javascript handler.
   1711   // Each item in the list has the following parameters:
   1712   // 1. Title (string).
   1713   // 2. Value (double).
   1714   // 3. Is selected? (bool).
   1715   ListValue zoom_factors_value;
   1716   for (std::vector<double>::const_iterator i = zoom_factors.begin();
   1717        i != zoom_factors.end(); ++i) {
   1718     ListValue* option = new ListValue();
   1719     double factor = *i;
   1720     int percent = static_cast<int>(factor * 100 + 0.5);
   1721     option->Append(new base::StringValue(
   1722         l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, percent)));
   1723     option->Append(new base::FundamentalValue(factor));
   1724     bool selected = content::ZoomValuesEqual(factor, default_zoom_factor);
   1725     option->Append(new base::FundamentalValue(selected));
   1726     zoom_factors_value.Append(option);
   1727   }
   1728 
   1729   web_ui()->CallJavascriptFunction(
   1730       "BrowserOptions.setupPageZoomSelector", zoom_factors_value);
   1731 }
   1732 
   1733 void BrowserOptionsHandler::SetupAutoOpenFileTypes() {
   1734   // Set the hidden state for the AutoOpenFileTypesResetToDefault button.
   1735   // We show the button if the user has any auto-open file types registered.
   1736   DownloadManager* manager = BrowserContext::GetDownloadManager(
   1737       web_ui()->GetWebContents()->GetBrowserContext());
   1738   bool display = manager &&
   1739       DownloadPrefs::FromDownloadManager(manager)->IsAutoOpenUsed();
   1740   base::FundamentalValue value(display);
   1741   web_ui()->CallJavascriptFunction(
   1742       "BrowserOptions.setAutoOpenFileTypesDisplayed", value);
   1743 }
   1744 
   1745 void BrowserOptionsHandler::SetupProxySettingsSection() {
   1746 #if !defined(OS_CHROMEOS)
   1747   // Disable the button if proxy settings are managed by a sysadmin or
   1748   // overridden by an extension.
   1749   PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
   1750   const PrefService::Preference* proxy_config =
   1751       pref_service->FindPreference(prefs::kProxy);
   1752   bool is_extension_controlled = (proxy_config &&
   1753                                   proxy_config->IsExtensionControlled());
   1754 
   1755   base::FundamentalValue disabled(proxy_config &&
   1756                                   !proxy_config->IsUserModifiable());
   1757   base::FundamentalValue extension_controlled(is_extension_controlled);
   1758   web_ui()->CallJavascriptFunction("BrowserOptions.setupProxySettingsSection",
   1759                                    disabled, extension_controlled);
   1760 
   1761 #endif  // !defined(OS_CHROMEOS)
   1762 }
   1763 
   1764 bool BrowserOptionsHandler::IsValidExistingManagedUserId(
   1765     const std::string& existing_managed_user_id) const {
   1766   if (existing_managed_user_id.empty())
   1767     return true;
   1768 
   1769   if (!CommandLine::ForCurrentProcess()->HasSwitch(
   1770       switches::kAllowCreateExistingManagedUsers)) {
   1771     return false;
   1772   }
   1773 
   1774   DictionaryPrefUpdate update(Profile::FromWebUI(web_ui())->GetPrefs(),
   1775                               prefs::kManagedUsers);
   1776   DictionaryValue* dict = update.Get();
   1777   if (!dict->HasKey(existing_managed_user_id))
   1778     return false;
   1779 
   1780   // Check if this managed user already exists on this machine.
   1781   const ProfileInfoCache& cache =
   1782       g_browser_process->profile_manager()->GetProfileInfoCache();
   1783   for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
   1784     if (existing_managed_user_id == cache.GetManagedUserIdOfProfileAtIndex(i))
   1785       return false;
   1786   }
   1787   return true;
   1788 }
   1789 
   1790 }  // namespace options
   1791