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"
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"
51 static const char kFallbackInputMethodLocale
[] = "en-US";
53 Preferences::Preferences()
55 input_method_manager_(input_method::InputMethodManager::Get()),
57 user_is_primary_(false) {
58 // Do not observe shell, if there is no shell instance; e.g., in some unit
60 if (ash::Shell::HasInstance())
61 ash::Shell::GetInstance()->AddShellObserver(this);
64 Preferences::Preferences(input_method::InputMethodManager
* input_method_manager
)
66 input_method_manager_(input_method_manager
),
68 user_is_primary_(false) {
69 // Do not observe shell, if there is no shell instance; e.g., in some unit
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);
85 void Preferences::RegisterPrefs(PrefRegistrySimple
* registry
) {
86 registry
->RegisterBooleanPref(prefs::kOwnerPrimaryMouseButtonRight
, false);
87 registry
->RegisterBooleanPref(prefs::kOwnerTapToClickEnabled
, true);
88 registry
->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled
,
90 registry
->RegisterStringPref(prefs::kLogoutStartedLast
, std::string());
91 registry
->RegisterBooleanPref(prefs::kResolveDeviceTimezoneByGeolocation
,
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();
104 hardware_keyboard_id
=
105 local_state
->GetString(prefs::kHardwareKeyboardLayout
);
107 hardware_keyboard_id
= "xkb:us::eng"; // only for testing.
110 registry
->RegisterBooleanPref(
111 prefs::kPerformanceTracingEnabled
,
113 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
115 registry
->RegisterBooleanPref(
116 prefs::kTapToClickEnabled
,
118 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
119 registry
->RegisterBooleanPref(
120 prefs::kTapDraggingEnabled
,
122 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
123 registry
->RegisterBooleanPref(
124 prefs::kEnableTouchpadThreeFingerClick
,
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
,
134 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
135 registry
->RegisterBooleanPref(
136 prefs::kLabsMediaplayerEnabled
,
138 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
139 registry
->RegisterBooleanPref(
140 prefs::kLabsAdvancedFilesystemEnabled
,
142 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
143 registry
->RegisterBooleanPref(
144 prefs::kAccessibilityStickyKeysEnabled
,
146 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
147 registry
->RegisterBooleanPref(
148 prefs::kAccessibilityLargeCursorEnabled
,
150 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
151 registry
->RegisterBooleanPref(
152 prefs::kAccessibilitySpokenFeedbackEnabled
,
154 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
155 registry
->RegisterBooleanPref(
156 prefs::kAccessibilityHighContrastEnabled
,
158 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
159 registry
->RegisterBooleanPref(
160 prefs::kAccessibilityScreenMagnifierEnabled
,
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
,
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
,
182 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
183 registry
->RegisterBooleanPref(
184 prefs::kShouldAlwaysShowAccessibilityMenu
,
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
,
202 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
203 registry
->RegisterBooleanPref(
204 prefs::kDisableDriveOverCellular
,
206 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
207 registry
->RegisterBooleanPref(
208 prefs::kDisableDriveHostedFiles
,
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
260 registry
->RegisterBooleanPref(
261 prefs::kLanguageSendFunctionKeys
,
263 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
264 registry
->RegisterBooleanPref(
265 prefs::kLanguageXkbAutoRepeatEnabled
,
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
,
281 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
283 // Mobile plan notifications default to on.
284 registry
->RegisterBooleanPref(
285 prefs::kShowPlanNotifications
,
287 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
289 // 3G first-time usage promo will be shown at least once.
290 registry
->RegisterBooleanPref(
291 prefs::kShow3gPromoNotification
,
293 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
295 // Initially all existing users would see "What's new" for current version
297 registry
->RegisterStringPref(prefs::kChromeOSReleaseNotesVersion
,
299 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
301 registry
->RegisterBooleanPref(
302 prefs::kExternalStorageDisabled
,
304 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
306 registry
->RegisterStringPref(
307 prefs::kTermsOfServiceURL
,
309 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
311 registry
->RegisterBooleanPref(
312 prefs::kTouchHudProjectionEnabled
,
314 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
316 registry
->RegisterBooleanPref(
317 prefs::kTouchVirtualKeyboardEnabled
,
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
) {
335 BooleanPrefMember::NamedChangeCallback callback
=
336 base::Bind(&Preferences::OnPreferenceChanged
, base::Unretained(this));
338 performance_tracing_enabled_
.Init(prefs::kPerformanceTracingEnabled
,
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
,
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
,
349 download_default_directory_
.Init(prefs::kDownloadDefaultDirectory
,
351 touch_hud_projection_enabled_
.Init(prefs::kTouchHudProjectionEnabled
,
353 preload_engines_
.Init(prefs::kLanguagePreloadEngines
, prefs
, callback
);
354 enabled_extension_imes_
.Init(prefs::kLanguageEnabledExtensionImes
,
356 current_input_method_
.Init(prefs::kLanguageCurrentInputMethod
,
358 previous_input_method_
.Init(prefs::kLanguagePreviousInputMethod
,
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
) {
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);
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
) {
418 ime_state_
= ime_state
;
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();
452 tracing_manager_
= TracingManager::Create();
454 tracing_manager_
.reset();
456 if (reason
!= REASON_PREF_CHANGED
|| pref_name
== prefs::kTapToClickEnabled
) {
457 const bool enabled
= tap_to_click_enabled_
.GetValue();
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.
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();
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();
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
495 ForceNaturalScrollDefault();
497 const bool enabled
= natural_scroll_
.GetValue();
498 DVLOG(1) << "Natural scroll set to " << enabled
;
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();
509 mouse_settings
.SetSensitivity(sensitivity
);
510 if (reason
== REASON_PREF_CHANGED
) {
511 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Changed",
513 system::kMaxPointerSensitivity
+ 1);
514 } else if (reason
== REASON_INITIALIZATION
) {
515 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Started",
517 system::kMaxPointerSensitivity
+ 1);
520 if (reason
!= REASON_PREF_CHANGED
||
521 pref_name
== prefs::kTouchpadSensitivity
) {
522 const int sensitivity
= touchpad_sensitivity_
.GetValue();
524 touchpad_settings
.SetSensitivity(sensitivity
);
525 if (reason
== REASON_PREF_CHANGED
) {
526 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Changed",
528 system::kMaxPointerSensitivity
+ 1);
529 } else if (reason
== REASON_INITIALIZATION
) {
530 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Started",
532 system::kMaxPointerSensitivity
+ 1);
535 if (reason
!= REASON_PREF_CHANGED
||
536 pref_name
== prefs::kPrimaryMouseButtonRight
) {
537 const bool right
= primary_mouse_button_right_
.GetValue();
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.
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()
580 ->SetAutoRepeatEnabled(enabled
);
583 if (reason
!= REASON_PREF_CHANGED
||
584 pref_name
== prefs::kLanguageXkbAutoRepeatDelay
||
585 pref_name
== prefs::kLanguageXkbAutoRepeatInterval
) {
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
;
607 base::SplitString(value
, ',', &split_values
);
609 ime_state_
->SetEnabledExtensionImes(&split_values
);
612 if (user_is_active
) {
613 system::InputDeviceSettings::Get()->UpdateTouchpadSettings(
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
);
635 g_browser_process
->local_state()->SetBoolean(
636 prefs::kResolveDeviceTimezoneByGeolocation
, value
);
638 if (user_is_primary_
) {
640 g_browser_process
->platform_part()->GetTimezoneResolver()->Start();
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
,
671 const std::string
& value
) {
672 VLOG(1) << "Setting " << name
<< " to '" << value
<< "'";
674 std::vector
<std::string
> split_values
;
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
);
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()
724 ->SetAutoRepeatRate(rate
);
727 void Preferences::OnTouchHudProjectionToggled(bool enabled
) {
728 if (touch_hud_projection_enabled_
.GetValue() == enabled
)
730 if (!user_
->is_active())
732 touch_hud_projection_enabled_
.SetValue(enabled
);
735 void Preferences::ActiveUserChanged(const user_manager::User
* active_user
) {
736 if (active_user
!= user_
)
738 ApplyPreferences(REASON_ACTIVE_USER_CHANGED
, "");
741 } // namespace chromeos