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