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