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