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