Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / preferences.cc
blobd181107aeb5075ddcb9924ed715355fba79615a9
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.
5 #include "chrome/browser/chromeos/preferences.h"
7 #include <vector>
9 #include "ash/autoclick/autoclick_controller.h"
10 #include "ash/shell.h"
11 #include "base/command_line.h"
12 #include "base/i18n/time_formatting.h"
13 #include "base/metrics/histogram.h"
14 #include "base/prefs/pref_member.h"
15 #include "base/prefs/pref_registry_simple.h"
16 #include "base/prefs/scoped_user_pref_update.h"
17 #include "base/strings/string_split.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/sys_info.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
24 #include "chrome/browser/chromeos/drive/file_system_util.h"
25 #include "chrome/browser/chromeos/input_method/input_method_syncer.h"
26 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
27 #include "chrome/browser/chromeos/net/wake_on_wifi_manager.h"
28 #include "chrome/browser/chromeos/system/input_device_settings.h"
29 #include "chrome/browser/download/download_prefs.h"
30 #include "chrome/browser/prefs/pref_service_syncable.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h"
33 #include "chromeos/chromeos_switches.h"
34 #include "chromeos/system/statistics_provider.h"
35 #include "chromeos/timezone/timezone_resolver.h"
36 #include "components/feedback/tracing_manager.h"
37 #include "components/pref_registry/pref_registry_syncable.h"
38 #include "components/user_manager/user.h"
39 #include "content/public/browser/browser_thread.h"
40 #include "third_party/icu/source/i18n/unicode/timezone.h"
41 #include "ui/base/ime/chromeos/extension_ime_util.h"
42 #include "ui/base/ime/chromeos/ime_keyboard.h"
43 #include "ui/base/ime/chromeos/input_method_manager.h"
44 #include "ui/chromeos/accessibility_types.h"
45 #include "ui/events/event_constants.h"
46 #include "ui/events/event_utils.h"
47 #include "url/gurl.h"
49 namespace chromeos {
51 static const char kFallbackInputMethodLocale[] = "en-US";
53 Preferences::Preferences()
54 : prefs_(NULL),
55 input_method_manager_(input_method::InputMethodManager::Get()),
56 user_(NULL),
57 user_is_primary_(false) {
58 // Do not observe shell, if there is no shell instance; e.g., in some unit
59 // tests.
60 if (ash::Shell::HasInstance())
61 ash::Shell::GetInstance()->AddShellObserver(this);
64 Preferences::Preferences(input_method::InputMethodManager* input_method_manager)
65 : prefs_(NULL),
66 input_method_manager_(input_method_manager),
67 user_(NULL),
68 user_is_primary_(false) {
69 // Do not observe shell, if there is no shell instance; e.g., in some unit
70 // tests.
71 if (ash::Shell::HasInstance())
72 ash::Shell::GetInstance()->AddShellObserver(this);
75 Preferences::~Preferences() {
76 prefs_->RemoveObserver(this);
77 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
78 // If shell instance is destoryed before this preferences instance, there is
79 // no need to remove this shell observer.
80 if (ash::Shell::HasInstance())
81 ash::Shell::GetInstance()->RemoveShellObserver(this);
84 // static
85 void Preferences::RegisterPrefs(PrefRegistrySimple* registry) {
86 registry->RegisterBooleanPref(prefs::kOwnerPrimaryMouseButtonRight, false);
87 registry->RegisterBooleanPref(prefs::kOwnerTapToClickEnabled, true);
88 registry->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled,
89 false);
90 registry->RegisterStringPref(prefs::kLogoutStartedLast, std::string());
91 registry->RegisterBooleanPref(prefs::kResolveDeviceTimezoneByGeolocation,
92 true);
95 // static
96 void Preferences::RegisterProfilePrefs(
97 user_prefs::PrefRegistrySyncable* registry) {
98 std::string hardware_keyboard_id;
99 // TODO(yusukes): Remove the runtime hack.
100 if (base::SysInfo::IsRunningOnChromeOS()) {
101 DCHECK(g_browser_process);
102 PrefService* local_state = g_browser_process->local_state();
103 DCHECK(local_state);
104 hardware_keyboard_id =
105 local_state->GetString(prefs::kHardwareKeyboardLayout);
106 } else {
107 hardware_keyboard_id = "xkb:us::eng"; // only for testing.
110 registry->RegisterBooleanPref(
111 prefs::kPerformanceTracingEnabled,
112 false,
113 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
115 registry->RegisterBooleanPref(
116 prefs::kTapToClickEnabled,
117 true,
118 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
119 registry->RegisterBooleanPref(
120 prefs::kTapDraggingEnabled,
121 false,
122 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
123 registry->RegisterBooleanPref(
124 prefs::kEnableTouchpadThreeFingerClick,
125 false,
126 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
127 registry->RegisterBooleanPref(
128 prefs::kNaturalScroll, base::CommandLine::ForCurrentProcess()->HasSwitch(
129 switches::kNaturalScrollDefault),
130 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
131 registry->RegisterBooleanPref(
132 prefs::kPrimaryMouseButtonRight,
133 false,
134 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
135 registry->RegisterBooleanPref(
136 prefs::kLabsMediaplayerEnabled,
137 false,
138 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
139 registry->RegisterBooleanPref(
140 prefs::kLabsAdvancedFilesystemEnabled,
141 false,
142 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
143 registry->RegisterBooleanPref(
144 prefs::kAccessibilityStickyKeysEnabled,
145 false,
146 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
147 registry->RegisterBooleanPref(
148 prefs::kAccessibilityLargeCursorEnabled,
149 false,
150 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
151 registry->RegisterBooleanPref(
152 prefs::kAccessibilitySpokenFeedbackEnabled,
153 false,
154 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
155 registry->RegisterBooleanPref(
156 prefs::kAccessibilityHighContrastEnabled,
157 false,
158 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
159 registry->RegisterBooleanPref(
160 prefs::kAccessibilityScreenMagnifierEnabled,
161 false,
162 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
163 registry->RegisterIntegerPref(
164 prefs::kAccessibilityScreenMagnifierType,
165 ui::kDefaultMagnifierType,
166 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
167 registry->RegisterDoublePref(
168 prefs::kAccessibilityScreenMagnifierScale,
169 std::numeric_limits<double>::min(),
170 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
171 registry->RegisterBooleanPref(
172 prefs::kAccessibilityAutoclickEnabled,
173 false,
174 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
175 registry->RegisterIntegerPref(
176 prefs::kAccessibilityAutoclickDelayMs,
177 ash::AutoclickController::kDefaultAutoclickDelayMs,
178 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
179 registry->RegisterBooleanPref(
180 prefs::kAccessibilityVirtualKeyboardEnabled,
181 false,
182 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
183 registry->RegisterBooleanPref(
184 prefs::kShouldAlwaysShowAccessibilityMenu,
185 false,
186 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
187 registry->RegisterIntegerPref(
188 prefs::kMouseSensitivity,
190 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
191 registry->RegisterIntegerPref(
192 prefs::kTouchpadSensitivity,
194 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
195 registry->RegisterBooleanPref(
196 prefs::kUse24HourClock,
197 base::GetHourClockType() == base::k24HourClock,
198 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
199 registry->RegisterBooleanPref(
200 prefs::kDisableDrive,
201 false,
202 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
203 registry->RegisterBooleanPref(
204 prefs::kDisableDriveOverCellular,
205 true,
206 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
207 registry->RegisterBooleanPref(
208 prefs::kDisableDriveHostedFiles,
209 false,
210 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
211 // We don't sync prefs::kLanguageCurrentInputMethod and PreviousInputMethod
212 // because they're just used to track the logout state of the device.
213 registry->RegisterStringPref(
214 prefs::kLanguageCurrentInputMethod,
216 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
217 registry->RegisterStringPref(
218 prefs::kLanguagePreviousInputMethod,
220 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
221 registry->RegisterStringPref(
222 prefs::kLanguagePreferredLanguages,
223 kFallbackInputMethodLocale,
224 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
225 registry->RegisterStringPref(
226 prefs::kLanguagePreloadEngines,
227 hardware_keyboard_id,
228 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
229 registry->RegisterStringPref(
230 prefs::kLanguageEnabledExtensionImes,
232 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
234 registry->RegisterIntegerPref(
235 prefs::kLanguageRemapSearchKeyTo,
236 input_method::kSearchKey,
237 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
238 registry->RegisterIntegerPref(
239 prefs::kLanguageRemapControlKeyTo,
240 input_method::kControlKey,
241 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
242 registry->RegisterIntegerPref(
243 prefs::kLanguageRemapAltKeyTo,
244 input_method::kAltKey,
245 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
246 // We don't sync the CapsLock remapping pref, since the UI hides this pref
247 // on certain devices, so syncing a non-default value to a device that
248 // doesn't allow changing the pref would be odd. http://crbug.com/167237
249 registry->RegisterIntegerPref(
250 prefs::kLanguageRemapCapsLockKeyTo,
251 input_method::kCapsLockKey,
252 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
253 registry->RegisterIntegerPref(
254 prefs::kLanguageRemapDiamondKeyTo,
255 input_method::kControlKey,
256 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
257 // The following pref isn't synced since the user may desire a different value
258 // depending on whether an external keyboard is attached to a particular
259 // device.
260 registry->RegisterBooleanPref(
261 prefs::kLanguageSendFunctionKeys,
262 false,
263 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
264 registry->RegisterBooleanPref(
265 prefs::kLanguageXkbAutoRepeatEnabled,
266 true,
267 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
268 registry->RegisterIntegerPref(
269 prefs::kLanguageXkbAutoRepeatDelay,
270 language_prefs::kXkbAutoRepeatDelayInMs,
271 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
272 registry->RegisterIntegerPref(
273 prefs::kLanguageXkbAutoRepeatInterval,
274 language_prefs::kXkbAutoRepeatIntervalInMs,
275 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
277 // We don't sync wake-on-wifi related prefs because they are device specific.
278 registry->RegisterBooleanPref(
279 prefs::kWakeOnWifiSsid,
280 true,
281 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
283 // Mobile plan notifications default to on.
284 registry->RegisterBooleanPref(
285 prefs::kShowPlanNotifications,
286 true,
287 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
289 // 3G first-time usage promo will be shown at least once.
290 registry->RegisterBooleanPref(
291 prefs::kShow3gPromoNotification,
292 true,
293 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
295 // Initially all existing users would see "What's new" for current version
296 // after update.
297 registry->RegisterStringPref(prefs::kChromeOSReleaseNotesVersion,
298 "0.0.0.0",
299 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
301 registry->RegisterBooleanPref(
302 prefs::kExternalStorageDisabled,
303 false,
304 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
306 registry->RegisterStringPref(
307 prefs::kTermsOfServiceURL,
309 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
311 registry->RegisterBooleanPref(
312 prefs::kTouchHudProjectionEnabled,
313 false,
314 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
316 registry->RegisterBooleanPref(
317 prefs::kTouchVirtualKeyboardEnabled,
318 false,
319 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
321 input_method::InputMethodSyncer::RegisterProfilePrefs(registry);
323 registry->RegisterBooleanPref(
324 prefs::kResolveTimezoneByGeolocation, true,
325 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
327 registry->RegisterBooleanPref(
328 prefs::kCaptivePortalAuthenticationIgnoresProxy, true,
329 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
332 void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) {
333 prefs_ = prefs;
335 BooleanPrefMember::NamedChangeCallback callback =
336 base::Bind(&Preferences::OnPreferenceChanged, base::Unretained(this));
338 performance_tracing_enabled_.Init(prefs::kPerformanceTracingEnabled,
339 prefs, callback);
340 tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, callback);
341 tap_dragging_enabled_.Init(prefs::kTapDraggingEnabled, prefs, callback);
342 three_finger_click_enabled_.Init(prefs::kEnableTouchpadThreeFingerClick,
343 prefs, callback);
344 natural_scroll_.Init(prefs::kNaturalScroll, prefs, callback);
345 mouse_sensitivity_.Init(prefs::kMouseSensitivity, prefs, callback);
346 touchpad_sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, callback);
347 primary_mouse_button_right_.Init(prefs::kPrimaryMouseButtonRight,
348 prefs, callback);
349 download_default_directory_.Init(prefs::kDownloadDefaultDirectory,
350 prefs, callback);
351 touch_hud_projection_enabled_.Init(prefs::kTouchHudProjectionEnabled,
352 prefs, callback);
353 preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, callback);
354 enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes,
355 prefs, callback);
356 current_input_method_.Init(prefs::kLanguageCurrentInputMethod,
357 prefs, callback);
358 previous_input_method_.Init(prefs::kLanguagePreviousInputMethod,
359 prefs, callback);
361 xkb_auto_repeat_enabled_.Init(
362 prefs::kLanguageXkbAutoRepeatEnabled, prefs, callback);
363 xkb_auto_repeat_delay_pref_.Init(
364 prefs::kLanguageXkbAutoRepeatDelay, prefs, callback);
365 xkb_auto_repeat_interval_pref_.Init(
366 prefs::kLanguageXkbAutoRepeatInterval, prefs, callback);
368 wake_on_wifi_ssid_.Init(prefs::kWakeOnWifiSsid, prefs, callback);
370 pref_change_registrar_.Init(prefs);
371 pref_change_registrar_.Add(prefs::kResolveTimezoneByGeolocation, callback);
374 void Preferences::Init(Profile* profile, const user_manager::User* user) {
375 DCHECK(profile);
376 DCHECK(user);
377 PrefServiceSyncable* prefs = PrefServiceSyncable::FromProfile(profile);
378 // This causes OnIsSyncingChanged to be called when the value of
379 // PrefService::IsSyncing() changes.
380 prefs->AddObserver(this);
381 user_ = user;
382 user_is_primary_ =
383 user_manager::UserManager::Get()->GetPrimaryUser() == user_;
384 InitUserPrefs(prefs);
386 user_manager::UserManager::Get()->AddSessionStateObserver(this);
388 UserSessionManager* session_manager = UserSessionManager::GetInstance();
389 DCHECK(session_manager);
390 ime_state_ = session_manager->GetDefaultIMEState(profile);
392 // Initialize preferences to currently saved state.
393 ApplyPreferences(REASON_INITIALIZATION, "");
395 // Note that |ime_state_| was modified by ApplyPreferences(), and
396 // SetState() is modifying |current_input_method_| (via
397 // PersistUserInputMethod() ). This way SetState() here may be called only
398 // after ApplyPreferences().
399 input_method_manager_->SetState(ime_state_);
401 input_method_syncer_.reset(
402 new input_method::InputMethodSyncer(prefs, ime_state_));
403 input_method_syncer_->Initialize();
405 // If a guest is logged in, initialize the prefs as if this is the first
406 // login. For a regular user this is done in
407 // UserSessionManager::InitProfilePreferences().
408 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
409 switches::kGuestSession))
410 session_manager->SetFirstLoginPrefs(profile, std::string(), std::string());
413 void Preferences::InitUserPrefsForTesting(
414 PrefServiceSyncable* prefs,
415 const user_manager::User* user,
416 scoped_refptr<input_method::InputMethodManager::State> ime_state) {
417 user_ = user;
418 ime_state_ = ime_state;
420 if (ime_state.get())
421 input_method_manager_->SetState(ime_state);
423 InitUserPrefs(prefs);
425 input_method_syncer_.reset(
426 new input_method::InputMethodSyncer(prefs, ime_state_));
427 input_method_syncer_->Initialize();
430 void Preferences::SetInputMethodListForTesting() {
431 SetInputMethodList();
434 void Preferences::OnPreferenceChanged(const std::string& pref_name) {
435 ApplyPreferences(REASON_PREF_CHANGED, pref_name);
438 void Preferences::ApplyPreferences(ApplyReason reason,
439 const std::string& pref_name) {
440 DCHECK(reason != REASON_PREF_CHANGED || !pref_name.empty());
441 const bool user_is_owner =
442 user_manager::UserManager::Get()->GetOwnerEmail() == user_->email();
443 const bool user_is_active = user_->is_active();
445 system::TouchpadSettings touchpad_settings;
446 system::MouseSettings mouse_settings;
448 if (user_is_primary_ && (reason == REASON_INITIALIZATION ||
449 pref_name == prefs::kPerformanceTracingEnabled)) {
450 const bool enabled = performance_tracing_enabled_.GetValue();
451 if (enabled)
452 tracing_manager_ = TracingManager::Create();
453 else
454 tracing_manager_.reset();
456 if (reason != REASON_PREF_CHANGED || pref_name == prefs::kTapToClickEnabled) {
457 const bool enabled = tap_to_click_enabled_.GetValue();
458 if (user_is_active)
459 touchpad_settings.SetTapToClick(enabled);
460 if (reason == REASON_PREF_CHANGED)
461 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Changed", enabled);
462 else if (reason == REASON_INITIALIZATION)
463 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Started", enabled);
465 // Save owner preference in local state to use on login screen.
466 if (user_is_owner) {
467 PrefService* prefs = g_browser_process->local_state();
468 if (prefs->GetBoolean(prefs::kOwnerTapToClickEnabled) != enabled)
469 prefs->SetBoolean(prefs::kOwnerTapToClickEnabled, enabled);
472 if (reason != REASON_PREF_CHANGED ||
473 pref_name == prefs::kTapDraggingEnabled) {
474 const bool enabled = tap_dragging_enabled_.GetValue();
475 if (user_is_active)
476 touchpad_settings.SetTapDragging(enabled);
477 if (reason == REASON_PREF_CHANGED)
478 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Changed", enabled);
479 else if (reason == REASON_INITIALIZATION)
480 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Started", enabled);
482 if (reason != REASON_PREF_CHANGED ||
483 pref_name == prefs::kEnableTouchpadThreeFingerClick) {
484 const bool enabled = three_finger_click_enabled_.GetValue();
485 if (user_is_active)
486 touchpad_settings.SetThreeFingerClick(enabled);
487 if (reason == REASON_PREF_CHANGED)
488 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Changed", enabled);
489 else if (reason == REASON_INITIALIZATION)
490 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Started", enabled);
492 if (reason != REASON_PREF_CHANGED || pref_name == prefs::kNaturalScroll) {
493 // Force natural scroll default if we've sync'd and if the cmd line arg is
494 // set.
495 ForceNaturalScrollDefault();
497 const bool enabled = natural_scroll_.GetValue();
498 DVLOG(1) << "Natural scroll set to " << enabled;
499 if (user_is_active)
500 touchpad_settings.SetNaturalScroll(enabled);
501 if (reason == REASON_PREF_CHANGED)
502 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Changed", enabled);
503 else if (reason == REASON_INITIALIZATION)
504 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Started", enabled);
506 if (reason != REASON_PREF_CHANGED || pref_name == prefs::kMouseSensitivity) {
507 const int sensitivity = mouse_sensitivity_.GetValue();
508 if (user_is_active)
509 mouse_settings.SetSensitivity(sensitivity);
510 if (reason == REASON_PREF_CHANGED) {
511 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Changed",
512 sensitivity,
513 system::kMaxPointerSensitivity + 1);
514 } else if (reason == REASON_INITIALIZATION) {
515 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Started",
516 sensitivity,
517 system::kMaxPointerSensitivity + 1);
520 if (reason != REASON_PREF_CHANGED ||
521 pref_name == prefs::kTouchpadSensitivity) {
522 const int sensitivity = touchpad_sensitivity_.GetValue();
523 if (user_is_active)
524 touchpad_settings.SetSensitivity(sensitivity);
525 if (reason == REASON_PREF_CHANGED) {
526 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Changed",
527 sensitivity,
528 system::kMaxPointerSensitivity + 1);
529 } else if (reason == REASON_INITIALIZATION) {
530 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Started",
531 sensitivity,
532 system::kMaxPointerSensitivity + 1);
535 if (reason != REASON_PREF_CHANGED ||
536 pref_name == prefs::kPrimaryMouseButtonRight) {
537 const bool right = primary_mouse_button_right_.GetValue();
538 if (user_is_active)
539 mouse_settings.SetPrimaryButtonRight(right);
540 if (reason == REASON_PREF_CHANGED)
541 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Changed", right);
542 else if (reason == REASON_INITIALIZATION)
543 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Started", right);
544 // Save owner preference in local state to use on login screen.
545 if (user_is_owner) {
546 PrefService* prefs = g_browser_process->local_state();
547 if (prefs->GetBoolean(prefs::kOwnerPrimaryMouseButtonRight) != right)
548 prefs->SetBoolean(prefs::kOwnerPrimaryMouseButtonRight, right);
551 if (reason != REASON_PREF_CHANGED ||
552 pref_name == prefs::kDownloadDefaultDirectory) {
553 const bool default_download_to_drive = drive::util::IsUnderDriveMountPoint(
554 download_default_directory_.GetValue());
555 if (reason == REASON_PREF_CHANGED)
556 UMA_HISTOGRAM_BOOLEAN(
557 "FileBrowser.DownloadDestination.IsGoogleDrive.Changed",
558 default_download_to_drive);
559 else if (reason == REASON_INITIALIZATION)
560 UMA_HISTOGRAM_BOOLEAN(
561 "FileBrowser.DownloadDestination.IsGoogleDrive.Started",
562 default_download_to_drive);
564 if (reason != REASON_PREF_CHANGED ||
565 pref_name == prefs::kTouchHudProjectionEnabled) {
566 if (user_is_active) {
567 const bool enabled = touch_hud_projection_enabled_.GetValue();
568 // There may not be a shell, e.g., in some unit tests.
569 if (ash::Shell::HasInstance())
570 ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
574 if (reason != REASON_PREF_CHANGED ||
575 pref_name == prefs::kLanguageXkbAutoRepeatEnabled) {
576 if (user_is_active) {
577 const bool enabled = xkb_auto_repeat_enabled_.GetValue();
578 input_method::InputMethodManager::Get()
579 ->GetImeKeyboard()
580 ->SetAutoRepeatEnabled(enabled);
583 if (reason != REASON_PREF_CHANGED ||
584 pref_name == prefs::kLanguageXkbAutoRepeatDelay ||
585 pref_name == prefs::kLanguageXkbAutoRepeatInterval) {
586 if (user_is_active)
587 UpdateAutoRepeatRate();
590 if (reason == REASON_INITIALIZATION)
591 SetInputMethodList();
593 if (pref_name == prefs::kLanguagePreloadEngines &&
594 reason == REASON_PREF_CHANGED) {
595 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
596 language_prefs::kPreloadEnginesConfigName,
597 preload_engines_.GetValue());
600 if ((reason == REASON_INITIALIZATION) ||
601 (pref_name == prefs::kLanguageEnabledExtensionImes &&
602 reason == REASON_PREF_CHANGED)) {
603 std::string value(enabled_extension_imes_.GetValue());
605 std::vector<std::string> split_values;
606 if (!value.empty())
607 base::SplitString(value, ',', &split_values);
609 ime_state_->SetEnabledExtensionImes(&split_values);
612 if (user_is_active) {
613 system::InputDeviceSettings::Get()->UpdateTouchpadSettings(
614 touchpad_settings);
615 system::InputDeviceSettings::Get()->UpdateMouseSettings(mouse_settings);
618 if (user_is_primary_ && (reason != REASON_PREF_CHANGED ||
619 pref_name == prefs::kWakeOnWifiSsid)) {
620 int features = wake_on_wifi_ssid_.GetValue() ?
621 WakeOnWifiManager::WAKE_ON_SSID : WakeOnWifiManager::WAKE_ON_NONE;
622 // The flag enables wake on packets but doesn't update a preference.
623 if (base::CommandLine::ForCurrentProcess()->
624 HasSwitch(switches::kWakeOnPackets)) {
625 features |= WakeOnWifiManager::WAKE_ON_PACKET;
627 WakeOnWifiManager::Get()->OnPreferenceChanged(
628 static_cast<WakeOnWifiManager::WakeOnWifiFeature>(features));
631 if (pref_name == prefs::kResolveTimezoneByGeolocation &&
632 reason != REASON_ACTIVE_USER_CHANGED) {
633 const bool value = prefs_->GetBoolean(prefs::kResolveTimezoneByGeolocation);
634 if (user_is_owner) {
635 g_browser_process->local_state()->SetBoolean(
636 prefs::kResolveDeviceTimezoneByGeolocation, value);
638 if (user_is_primary_) {
639 if (value) {
640 g_browser_process->platform_part()->GetTimezoneResolver()->Start();
641 } else {
642 g_browser_process->platform_part()->GetTimezoneResolver()->Stop();
643 if (reason == REASON_PREF_CHANGED) {
644 // Allow immediate timezone update on Stop + Start.
645 g_browser_process->local_state()->ClearPref(
646 TimeZoneResolver::kLastTimeZoneRefreshTime);
653 void Preferences::OnIsSyncingChanged() {
654 DVLOG(1) << "OnIsSyncingChanged";
655 ForceNaturalScrollDefault();
658 void Preferences::ForceNaturalScrollDefault() {
659 DVLOG(1) << "ForceNaturalScrollDefault";
660 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
661 switches::kNaturalScrollDefault) &&
662 prefs_->IsSyncing() && !prefs_->GetUserPrefValue(prefs::kNaturalScroll)) {
663 DVLOG(1) << "Natural scroll forced to true";
664 natural_scroll_.SetValue(true);
665 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Forced", true);
669 void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
670 const char* name,
671 const std::string& value) {
672 VLOG(1) << "Setting " << name << " to '" << value << "'";
674 std::vector<std::string> split_values;
675 if (!value.empty())
676 base::SplitString(value, ',', &split_values);
678 // Transfers the xkb id to extension-xkb id.
679 if (input_method_manager_->MigrateInputMethods(&split_values))
680 preload_engines_.SetValue(JoinString(split_values, ','));
682 if (section == std::string(language_prefs::kGeneralSectionName) &&
683 name == std::string(language_prefs::kPreloadEnginesConfigName)) {
684 ime_state_->ReplaceEnabledInputMethods(split_values);
685 return;
689 void Preferences::SetInputMethodList() {
690 // When |preload_engines_| are set, InputMethodManager::ChangeInputMethod()
691 // might be called to change the current input method to the first one in the
692 // |preload_engines_| list. This also updates previous/current input method
693 // prefs. That's why GetValue() calls are placed before the
694 // SetLanguageConfigStringListAsCSV() call below.
695 const std::string previous_input_method_id =
696 previous_input_method_.GetValue();
697 const std::string current_input_method_id = current_input_method_.GetValue();
698 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
699 language_prefs::kPreloadEnginesConfigName,
700 preload_engines_.GetValue());
702 // ChangeInputMethod() has to be called AFTER the value of |preload_engines_|
703 // is sent to the InputMethodManager. Otherwise, the ChangeInputMethod request
704 // might be ignored as an invalid input method ID. The ChangeInputMethod()
705 // calls are also necessary to restore the previous/current input method prefs
706 // which could have been modified by the SetLanguageConfigStringListAsCSV call
707 // above to the original state.
708 if (!previous_input_method_id.empty())
709 ime_state_->ChangeInputMethod(previous_input_method_id,
710 false /* show_message */);
711 if (!current_input_method_id.empty())
712 ime_state_->ChangeInputMethod(current_input_method_id,
713 false /* show_message */);
716 void Preferences::UpdateAutoRepeatRate() {
717 input_method::AutoRepeatRate rate;
718 rate.initial_delay_in_ms = xkb_auto_repeat_delay_pref_.GetValue();
719 rate.repeat_interval_in_ms = xkb_auto_repeat_interval_pref_.GetValue();
720 DCHECK(rate.initial_delay_in_ms > 0);
721 DCHECK(rate.repeat_interval_in_ms > 0);
722 input_method::InputMethodManager::Get()
723 ->GetImeKeyboard()
724 ->SetAutoRepeatRate(rate);
727 void Preferences::OnTouchHudProjectionToggled(bool enabled) {
728 if (touch_hud_projection_enabled_.GetValue() == enabled)
729 return;
730 if (!user_->is_active())
731 return;
732 touch_hud_projection_enabled_.SetValue(enabled);
735 void Preferences::ActiveUserChanged(const user_manager::User* active_user) {
736 if (active_user != user_)
737 return;
738 ApplyPreferences(REASON_ACTIVE_USER_CHANGED, "");
741 } // namespace chromeos