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