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