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