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