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