Roll src/third_party/WebKit 8b42d1d:744641d (svn 186770:186771)
[chromium-blink-merge.git] / chrome / browser / chromeos / preferences.cc
blob6ab83e2f9f6e41b19920cf30e8dc5a7434cfd1d1
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 "components/feedback/tracing_manager.h"
36 #include "components/pref_registry/pref_registry_syncable.h"
37 #include "components/user_manager/user.h"
38 #include "content/public/browser/browser_thread.h"
39 #include "third_party/icu/source/i18n/unicode/timezone.h"
40 #include "ui/base/ime/chromeos/extension_ime_util.h"
41 #include "ui/base/ime/chromeos/ime_keyboard.h"
42 #include "ui/base/ime/chromeos/input_method_manager.h"
43 #include "ui/chromeos/accessibility_types.h"
44 #include "ui/events/event_constants.h"
45 #include "ui/events/event_utils.h"
46 #include "url/gurl.h"
48 namespace chromeos {
50 static const char kFallbackInputMethodLocale[] = "en-US";
52 Preferences::Preferences()
53 : prefs_(NULL),
54 input_method_manager_(input_method::InputMethodManager::Get()),
55 user_(NULL),
56 user_is_primary_(false) {
57 // Do not observe shell, if there is no shell instance; e.g., in some unit
58 // tests.
59 if (ash::Shell::HasInstance())
60 ash::Shell::GetInstance()->AddShellObserver(this);
63 Preferences::Preferences(input_method::InputMethodManager* input_method_manager)
64 : prefs_(NULL),
65 input_method_manager_(input_method_manager),
66 user_(NULL),
67 user_is_primary_(false) {
68 // Do not observe shell, if there is no shell instance; e.g., in some unit
69 // tests.
70 if (ash::Shell::HasInstance())
71 ash::Shell::GetInstance()->AddShellObserver(this);
74 Preferences::~Preferences() {
75 prefs_->RemoveObserver(this);
76 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
77 // If shell instance is destoryed before this preferences instance, there is
78 // no need to remove this shell observer.
79 if (ash::Shell::HasInstance())
80 ash::Shell::GetInstance()->RemoveShellObserver(this);
83 // static
84 void Preferences::RegisterPrefs(PrefRegistrySimple* registry) {
85 registry->RegisterBooleanPref(prefs::kOwnerPrimaryMouseButtonRight, false);
86 registry->RegisterBooleanPref(prefs::kOwnerTapToClickEnabled, true);
87 registry->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled,
88 false);
89 registry->RegisterStringPref(prefs::kLogoutStartedLast, std::string());
92 // static
93 void Preferences::RegisterProfilePrefs(
94 user_prefs::PrefRegistrySyncable* registry) {
95 std::string hardware_keyboard_id;
96 // TODO(yusukes): Remove the runtime hack.
97 if (base::SysInfo::IsRunningOnChromeOS()) {
98 DCHECK(g_browser_process);
99 PrefService* local_state = g_browser_process->local_state();
100 DCHECK(local_state);
101 hardware_keyboard_id =
102 local_state->GetString(prefs::kHardwareKeyboardLayout);
103 } else {
104 hardware_keyboard_id = "xkb:us::eng"; // only for testing.
107 registry->RegisterBooleanPref(
108 prefs::kPerformanceTracingEnabled,
109 false,
110 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
112 registry->RegisterBooleanPref(
113 prefs::kTapToClickEnabled,
114 true,
115 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
116 registry->RegisterBooleanPref(
117 prefs::kTapDraggingEnabled,
118 false,
119 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
120 registry->RegisterBooleanPref(
121 prefs::kEnableTouchpadThreeFingerClick,
122 false,
123 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
124 registry->RegisterBooleanPref(
125 prefs::kNaturalScroll,
126 CommandLine::ForCurrentProcess()->HasSwitch(
127 switches::kNaturalScrollDefault),
128 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
129 registry->RegisterBooleanPref(
130 prefs::kPrimaryMouseButtonRight,
131 false,
132 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
133 registry->RegisterBooleanPref(
134 prefs::kLabsMediaplayerEnabled,
135 false,
136 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
137 registry->RegisterBooleanPref(
138 prefs::kLabsAdvancedFilesystemEnabled,
139 false,
140 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
141 registry->RegisterBooleanPref(
142 prefs::kAccessibilityStickyKeysEnabled,
143 false,
144 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
145 registry->RegisterBooleanPref(
146 prefs::kAccessibilityLargeCursorEnabled,
147 false,
148 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
149 registry->RegisterBooleanPref(
150 prefs::kAccessibilitySpokenFeedbackEnabled,
151 false,
152 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
153 registry->RegisterBooleanPref(
154 prefs::kAccessibilityHighContrastEnabled,
155 false,
156 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
157 registry->RegisterBooleanPref(
158 prefs::kAccessibilityScreenMagnifierEnabled,
159 false,
160 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
161 registry->RegisterIntegerPref(
162 prefs::kAccessibilityScreenMagnifierType,
163 ui::kDefaultMagnifierType,
164 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
165 registry->RegisterDoublePref(
166 prefs::kAccessibilityScreenMagnifierScale,
167 std::numeric_limits<double>::min(),
168 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
169 registry->RegisterBooleanPref(
170 prefs::kAccessibilityAutoclickEnabled,
171 false,
172 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
173 registry->RegisterIntegerPref(
174 prefs::kAccessibilityAutoclickDelayMs,
175 ash::AutoclickController::kDefaultAutoclickDelayMs,
176 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
177 registry->RegisterBooleanPref(
178 prefs::kAccessibilityVirtualKeyboardEnabled,
179 false,
180 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
181 registry->RegisterBooleanPref(
182 prefs::kShouldAlwaysShowAccessibilityMenu,
183 false,
184 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
185 registry->RegisterIntegerPref(
186 prefs::kMouseSensitivity,
188 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
189 registry->RegisterIntegerPref(
190 prefs::kTouchpadSensitivity,
192 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
193 registry->RegisterBooleanPref(
194 prefs::kUse24HourClock,
195 base::GetHourClockType() == base::k24HourClock,
196 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
197 registry->RegisterBooleanPref(
198 prefs::kDisableDrive,
199 false,
200 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
201 registry->RegisterBooleanPref(
202 prefs::kDisableDriveOverCellular,
203 true,
204 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
205 registry->RegisterBooleanPref(
206 prefs::kDisableDriveHostedFiles,
207 false,
208 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
209 // We don't sync prefs::kLanguageCurrentInputMethod and PreviousInputMethod
210 // because they're just used to track the logout state of the device.
211 registry->RegisterStringPref(
212 prefs::kLanguageCurrentInputMethod,
214 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
215 registry->RegisterStringPref(
216 prefs::kLanguagePreviousInputMethod,
218 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
219 registry->RegisterStringPref(
220 prefs::kLanguagePreferredLanguages,
221 kFallbackInputMethodLocale,
222 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
223 registry->RegisterStringPref(
224 prefs::kLanguagePreloadEngines,
225 hardware_keyboard_id,
226 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
227 registry->RegisterStringPref(
228 prefs::kLanguageEnabledExtensionImes,
230 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
232 registry->RegisterIntegerPref(
233 prefs::kLanguageRemapSearchKeyTo,
234 input_method::kSearchKey,
235 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
236 registry->RegisterIntegerPref(
237 prefs::kLanguageRemapControlKeyTo,
238 input_method::kControlKey,
239 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
240 registry->RegisterIntegerPref(
241 prefs::kLanguageRemapAltKeyTo,
242 input_method::kAltKey,
243 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
244 // We don't sync the CapsLock remapping pref, since the UI hides this pref
245 // on certain devices, so syncing a non-default value to a device that
246 // doesn't allow changing the pref would be odd. http://crbug.com/167237
247 registry->RegisterIntegerPref(
248 prefs::kLanguageRemapCapsLockKeyTo,
249 input_method::kCapsLockKey,
250 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
251 registry->RegisterIntegerPref(
252 prefs::kLanguageRemapDiamondKeyTo,
253 input_method::kControlKey,
254 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
255 // The following pref isn't synced since the user may desire a different value
256 // depending on whether an external keyboard is attached to a particular
257 // device.
258 registry->RegisterBooleanPref(
259 prefs::kLanguageSendFunctionKeys,
260 false,
261 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
262 registry->RegisterBooleanPref(
263 prefs::kLanguageXkbAutoRepeatEnabled,
264 true,
265 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
266 registry->RegisterIntegerPref(
267 prefs::kLanguageXkbAutoRepeatDelay,
268 language_prefs::kXkbAutoRepeatDelayInMs,
269 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
270 registry->RegisterIntegerPref(
271 prefs::kLanguageXkbAutoRepeatInterval,
272 language_prefs::kXkbAutoRepeatIntervalInMs,
273 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
275 // We don't sync wake-on-wifi related prefs because they are device specific.
276 // TODO(chirantan): Default this to on when we are ready to launch.
277 registry->RegisterIntegerPref(
278 prefs::kWakeOnWiFiEnabled,
279 base::CommandLine::ForCurrentProcess()->HasSwitch(
280 switches::kWakeOnPackets)
281 ? WakeOnWifiManager::WAKE_ON_PACKET_AND_SSID
282 : WakeOnWifiManager::WAKE_ON_NONE,
283 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
285 // Mobile plan notifications default to on.
286 registry->RegisterBooleanPref(
287 prefs::kShowPlanNotifications,
288 true,
289 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
291 // 3G first-time usage promo will be shown at least once.
292 registry->RegisterBooleanPref(
293 prefs::kShow3gPromoNotification,
294 true,
295 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
297 // Initially all existing users would see "What's new" for current version
298 // after update.
299 registry->RegisterStringPref(prefs::kChromeOSReleaseNotesVersion,
300 "0.0.0.0",
301 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
303 registry->RegisterBooleanPref(
304 prefs::kExternalStorageDisabled,
305 false,
306 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
308 registry->RegisterStringPref(
309 prefs::kTermsOfServiceURL,
311 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
313 registry->RegisterBooleanPref(
314 prefs::kTouchHudProjectionEnabled,
315 false,
316 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
318 registry->RegisterBooleanPref(
319 prefs::kTouchVirtualKeyboardEnabled,
320 false,
321 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
323 input_method::InputMethodSyncer::RegisterProfilePrefs(registry);
326 void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) {
327 prefs_ = prefs;
329 BooleanPrefMember::NamedChangeCallback callback =
330 base::Bind(&Preferences::OnPreferenceChanged, base::Unretained(this));
332 performance_tracing_enabled_.Init(prefs::kPerformanceTracingEnabled,
333 prefs, callback);
334 tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, callback);
335 tap_dragging_enabled_.Init(prefs::kTapDraggingEnabled, prefs, callback);
336 three_finger_click_enabled_.Init(prefs::kEnableTouchpadThreeFingerClick,
337 prefs, callback);
338 natural_scroll_.Init(prefs::kNaturalScroll, prefs, callback);
339 mouse_sensitivity_.Init(prefs::kMouseSensitivity, prefs, callback);
340 touchpad_sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, callback);
341 primary_mouse_button_right_.Init(prefs::kPrimaryMouseButtonRight,
342 prefs, callback);
343 download_default_directory_.Init(prefs::kDownloadDefaultDirectory,
344 prefs, callback);
345 touch_hud_projection_enabled_.Init(prefs::kTouchHudProjectionEnabled,
346 prefs, callback);
347 preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, callback);
348 enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes,
349 prefs, callback);
350 current_input_method_.Init(prefs::kLanguageCurrentInputMethod,
351 prefs, callback);
352 previous_input_method_.Init(prefs::kLanguagePreviousInputMethod,
353 prefs, callback);
355 xkb_auto_repeat_enabled_.Init(
356 prefs::kLanguageXkbAutoRepeatEnabled, prefs, callback);
357 xkb_auto_repeat_delay_pref_.Init(
358 prefs::kLanguageXkbAutoRepeatDelay, prefs, callback);
359 xkb_auto_repeat_interval_pref_.Init(
360 prefs::kLanguageXkbAutoRepeatInterval, prefs, callback);
362 wake_on_wifi_enabled_.Init(prefs::kWakeOnWiFiEnabled, prefs, callback);
365 void Preferences::Init(Profile* profile, const user_manager::User* user) {
366 DCHECK(profile);
367 DCHECK(user);
368 PrefServiceSyncable* prefs = PrefServiceSyncable::FromProfile(profile);
369 // This causes OnIsSyncingChanged to be called when the value of
370 // PrefService::IsSyncing() changes.
371 prefs->AddObserver(this);
372 user_ = user;
373 user_is_primary_ =
374 user_manager::UserManager::Get()->GetPrimaryUser() == user_;
375 InitUserPrefs(prefs);
377 user_manager::UserManager::Get()->AddSessionStateObserver(this);
379 UserSessionManager* session_manager = UserSessionManager::GetInstance();
380 DCHECK(session_manager);
381 ime_state_ = session_manager->GetDefaultIMEState(profile);
382 input_method_manager_->SetState(ime_state_);
384 // Initialize preferences to currently saved state.
385 ApplyPreferences(REASON_INITIALIZATION, "");
386 input_method_syncer_.reset(
387 new input_method::InputMethodSyncer(prefs, ime_state_));
388 input_method_syncer_->Initialize();
390 // If a guest is logged in, initialize the prefs as if this is the first
391 // login. For a regular user this is done in
392 // UserSessionManager::InitProfilePreferences().
393 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession))
394 session_manager->SetFirstLoginPrefs(profile, std::string(), std::string());
397 void Preferences::InitUserPrefsForTesting(
398 PrefServiceSyncable* prefs,
399 const user_manager::User* user,
400 scoped_refptr<input_method::InputMethodManager::State> ime_state) {
401 user_ = user;
402 ime_state_ = ime_state;
404 if (ime_state.get())
405 input_method_manager_->SetState(ime_state);
407 InitUserPrefs(prefs);
409 input_method_syncer_.reset(
410 new input_method::InputMethodSyncer(prefs, ime_state_));
411 input_method_syncer_->Initialize();
414 void Preferences::SetInputMethodListForTesting() {
415 SetInputMethodList();
418 void Preferences::OnPreferenceChanged(const std::string& pref_name) {
419 ApplyPreferences(REASON_PREF_CHANGED, pref_name);
422 void Preferences::ApplyPreferences(ApplyReason reason,
423 const std::string& pref_name) {
424 DCHECK(reason != REASON_PREF_CHANGED || !pref_name.empty());
425 const bool user_is_owner =
426 user_manager::UserManager::Get()->GetOwnerEmail() == user_->email();
427 const bool user_is_active = user_->is_active();
429 system::TouchpadSettings touchpad_settings;
430 system::MouseSettings mouse_settings;
432 if (user_is_primary_ && (reason == REASON_INITIALIZATION ||
433 pref_name == prefs::kPerformanceTracingEnabled)) {
434 const bool enabled = performance_tracing_enabled_.GetValue();
435 if (enabled)
436 tracing_manager_ = TracingManager::Create();
437 else
438 tracing_manager_.reset();
440 if (reason != REASON_PREF_CHANGED || pref_name == prefs::kTapToClickEnabled) {
441 const bool enabled = tap_to_click_enabled_.GetValue();
442 if (user_is_active)
443 touchpad_settings.SetTapToClick(enabled);
444 if (reason == REASON_PREF_CHANGED)
445 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Changed", enabled);
446 else if (reason == REASON_INITIALIZATION)
447 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Started", enabled);
449 // Save owner preference in local state to use on login screen.
450 if (user_is_owner) {
451 PrefService* prefs = g_browser_process->local_state();
452 if (prefs->GetBoolean(prefs::kOwnerTapToClickEnabled) != enabled)
453 prefs->SetBoolean(prefs::kOwnerTapToClickEnabled, enabled);
456 if (reason != REASON_PREF_CHANGED ||
457 pref_name == prefs::kTapDraggingEnabled) {
458 const bool enabled = tap_dragging_enabled_.GetValue();
459 if (user_is_active)
460 touchpad_settings.SetTapDragging(enabled);
461 if (reason == REASON_PREF_CHANGED)
462 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Changed", enabled);
463 else if (reason == REASON_INITIALIZATION)
464 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Started", enabled);
466 if (reason != REASON_PREF_CHANGED ||
467 pref_name == prefs::kEnableTouchpadThreeFingerClick) {
468 const bool enabled = three_finger_click_enabled_.GetValue();
469 if (user_is_active)
470 touchpad_settings.SetThreeFingerClick(enabled);
471 if (reason == REASON_PREF_CHANGED)
472 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Changed", enabled);
473 else if (reason == REASON_INITIALIZATION)
474 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Started", enabled);
476 if (reason != REASON_PREF_CHANGED || pref_name == prefs::kNaturalScroll) {
477 // Force natural scroll default if we've sync'd and if the cmd line arg is
478 // set.
479 ForceNaturalScrollDefault();
481 const bool enabled = natural_scroll_.GetValue();
482 DVLOG(1) << "Natural scroll set to " << enabled;
483 if (user_is_active)
484 touchpad_settings.SetNaturalScroll(enabled);
485 if (reason == REASON_PREF_CHANGED)
486 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Changed", enabled);
487 else if (reason == REASON_INITIALIZATION)
488 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Started", enabled);
490 if (reason != REASON_PREF_CHANGED || pref_name == prefs::kMouseSensitivity) {
491 const int sensitivity = mouse_sensitivity_.GetValue();
492 if (user_is_active)
493 mouse_settings.SetSensitivity(sensitivity);
494 if (reason == REASON_PREF_CHANGED) {
495 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Changed",
496 sensitivity,
497 system::kMaxPointerSensitivity + 1);
498 } else if (reason == REASON_INITIALIZATION) {
499 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Started",
500 sensitivity,
501 system::kMaxPointerSensitivity + 1);
504 if (reason != REASON_PREF_CHANGED ||
505 pref_name == prefs::kTouchpadSensitivity) {
506 const int sensitivity = touchpad_sensitivity_.GetValue();
507 if (user_is_active)
508 touchpad_settings.SetSensitivity(sensitivity);
509 if (reason == REASON_PREF_CHANGED) {
510 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Changed",
511 sensitivity,
512 system::kMaxPointerSensitivity + 1);
513 } else if (reason == REASON_INITIALIZATION) {
514 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Started",
515 sensitivity,
516 system::kMaxPointerSensitivity + 1);
519 if (reason != REASON_PREF_CHANGED ||
520 pref_name == prefs::kPrimaryMouseButtonRight) {
521 const bool right = primary_mouse_button_right_.GetValue();
522 if (user_is_active)
523 mouse_settings.SetPrimaryButtonRight(right);
524 if (reason == REASON_PREF_CHANGED)
525 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Changed", right);
526 else if (reason == REASON_INITIALIZATION)
527 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Started", right);
528 // Save owner preference in local state to use on login screen.
529 if (user_is_owner) {
530 PrefService* prefs = g_browser_process->local_state();
531 if (prefs->GetBoolean(prefs::kOwnerPrimaryMouseButtonRight) != right)
532 prefs->SetBoolean(prefs::kOwnerPrimaryMouseButtonRight, right);
535 if (reason != REASON_PREF_CHANGED ||
536 pref_name == prefs::kDownloadDefaultDirectory) {
537 const bool default_download_to_drive = drive::util::IsUnderDriveMountPoint(
538 download_default_directory_.GetValue());
539 if (reason == REASON_PREF_CHANGED)
540 UMA_HISTOGRAM_BOOLEAN(
541 "FileBrowser.DownloadDestination.IsGoogleDrive.Changed",
542 default_download_to_drive);
543 else if (reason == REASON_INITIALIZATION)
544 UMA_HISTOGRAM_BOOLEAN(
545 "FileBrowser.DownloadDestination.IsGoogleDrive.Started",
546 default_download_to_drive);
548 if (reason != REASON_PREF_CHANGED ||
549 pref_name == prefs::kTouchHudProjectionEnabled) {
550 #if !defined(USE_ATHENA)
551 if (user_is_active) {
552 const bool enabled = touch_hud_projection_enabled_.GetValue();
553 // There may not be a shell, e.g., in some unit tests.
554 if (ash::Shell::HasInstance())
555 ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
557 #endif
560 if (reason != REASON_PREF_CHANGED ||
561 pref_name == prefs::kLanguageXkbAutoRepeatEnabled) {
562 if (user_is_active) {
563 const bool enabled = xkb_auto_repeat_enabled_.GetValue();
564 input_method::InputMethodManager::Get()
565 ->GetImeKeyboard()
566 ->SetAutoRepeatEnabled(enabled);
569 if (reason != REASON_PREF_CHANGED ||
570 pref_name == prefs::kLanguageXkbAutoRepeatDelay ||
571 pref_name == prefs::kLanguageXkbAutoRepeatInterval) {
572 if (user_is_active)
573 UpdateAutoRepeatRate();
576 if (user_is_primary_ && (reason != REASON_PREF_CHANGED ||
577 pref_name == prefs::kWakeOnWiFiEnabled)) {
578 WakeOnWifiManager::Get()->OnPreferenceChanged(
579 static_cast<WakeOnWifiManager::WakeOnWifiFeature>(
580 wake_on_wifi_enabled_.GetValue()));
583 if (reason == REASON_INITIALIZATION)
584 SetInputMethodList();
586 if (pref_name == prefs::kLanguagePreloadEngines &&
587 reason == REASON_PREF_CHANGED) {
588 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
589 language_prefs::kPreloadEnginesConfigName,
590 preload_engines_.GetValue());
593 if ((reason == REASON_INITIALIZATION) ||
594 (pref_name == prefs::kLanguageEnabledExtensionImes &&
595 reason == REASON_PREF_CHANGED)) {
596 std::string value(enabled_extension_imes_.GetValue());
598 std::vector<std::string> split_values;
599 if (!value.empty())
600 base::SplitString(value, ',', &split_values);
602 ime_state_->SetEnabledExtensionImes(&split_values);
605 if (user_is_active) {
606 system::InputDeviceSettings::Get()->UpdateTouchpadSettings(
607 touchpad_settings);
608 system::InputDeviceSettings::Get()->UpdateMouseSettings(mouse_settings);
612 void Preferences::OnIsSyncingChanged() {
613 DVLOG(1) << "OnIsSyncingChanged";
614 ForceNaturalScrollDefault();
617 void Preferences::ForceNaturalScrollDefault() {
618 DVLOG(1) << "ForceNaturalScrollDefault";
619 if (CommandLine::ForCurrentProcess()->HasSwitch(
620 switches::kNaturalScrollDefault) &&
621 prefs_->IsSyncing() &&
622 !prefs_->GetUserPrefValue(prefs::kNaturalScroll)) {
623 DVLOG(1) << "Natural scroll forced to true";
624 natural_scroll_.SetValue(true);
625 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Forced", true);
629 void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
630 const char* name,
631 const std::string& value) {
632 VLOG(1) << "Setting " << name << " to '" << value << "'";
634 std::vector<std::string> split_values;
635 if (!value.empty())
636 base::SplitString(value, ',', &split_values);
638 // Transfers the xkb id to extension-xkb id.
639 if (input_method_manager_->MigrateInputMethods(&split_values))
640 preload_engines_.SetValue(JoinString(split_values, ','));
642 if (section == std::string(language_prefs::kGeneralSectionName) &&
643 name == std::string(language_prefs::kPreloadEnginesConfigName)) {
644 ime_state_->ReplaceEnabledInputMethods(split_values);
645 return;
649 void Preferences::SetInputMethodList() {
650 // When |preload_engines_| are set, InputMethodManager::ChangeInputMethod()
651 // might be called to change the current input method to the first one in the
652 // |preload_engines_| list. This also updates previous/current input method
653 // prefs. That's why GetValue() calls are placed before the
654 // SetLanguageConfigStringListAsCSV() call below.
655 const std::string previous_input_method_id =
656 previous_input_method_.GetValue();
657 const std::string current_input_method_id = current_input_method_.GetValue();
658 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
659 language_prefs::kPreloadEnginesConfigName,
660 preload_engines_.GetValue());
662 // ChangeInputMethod() has to be called AFTER the value of |preload_engines_|
663 // is sent to the InputMethodManager. Otherwise, the ChangeInputMethod request
664 // might be ignored as an invalid input method ID. The ChangeInputMethod()
665 // calls are also necessary to restore the previous/current input method prefs
666 // which could have been modified by the SetLanguageConfigStringListAsCSV call
667 // above to the original state.
668 if (!previous_input_method_id.empty())
669 ime_state_->ChangeInputMethod(previous_input_method_id,
670 false /* show_message */);
671 if (!current_input_method_id.empty())
672 ime_state_->ChangeInputMethod(current_input_method_id,
673 false /* show_message */);
676 void Preferences::UpdateAutoRepeatRate() {
677 input_method::AutoRepeatRate rate;
678 rate.initial_delay_in_ms = xkb_auto_repeat_delay_pref_.GetValue();
679 rate.repeat_interval_in_ms = xkb_auto_repeat_interval_pref_.GetValue();
680 DCHECK(rate.initial_delay_in_ms > 0);
681 DCHECK(rate.repeat_interval_in_ms > 0);
682 input_method::InputMethodManager::Get()
683 ->GetImeKeyboard()
684 ->SetAutoRepeatRate(rate);
687 void Preferences::OnTouchHudProjectionToggled(bool enabled) {
688 if (touch_hud_projection_enabled_.GetValue() == enabled)
689 return;
690 if (!user_->is_active())
691 return;
692 touch_hud_projection_enabled_.SetValue(enabled);
695 void Preferences::ActiveUserChanged(const user_manager::User* active_user) {
696 if (active_user != user_)
697 return;
698 ApplyPreferences(REASON_ACTIVE_USER_CHANGED, "");
701 } // namespace chromeos