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_util.h"
26 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
27 #include "chrome/browser/chromeos/profiles/profile_helper.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/ime/extension_ime_util.h"
35 #include "chromeos/ime/ime_keyboard.h"
36 #include "chromeos/ime/input_method_manager.h"
37 #include "chromeos/system/statistics_provider.h"
38 #include "components/feedback/tracing_manager.h"
39 #include "components/pref_registry/pref_registry_syncable.h"
40 #include "components/user_manager/user.h"
41 #include "third_party/icu/source/i18n/unicode/timezone.h"
42 #include "ui/chromeos/accessibility_types.h"
43 #include "ui/events/event_constants.h"
44 #include "ui/events/event_utils.h"
49 static const char kFallbackInputMethodLocale
[] = "en-US";
51 Preferences::Preferences()
53 input_method_manager_(input_method::InputMethodManager::Get()),
55 user_is_primary_(false) {
56 // Do not observe shell, if there is no shell instance; e.g., in some unit
58 if (ash::Shell::HasInstance())
59 ash::Shell::GetInstance()->AddShellObserver(this);
62 Preferences::Preferences(input_method::InputMethodManager
* input_method_manager
)
64 input_method_manager_(input_method_manager
),
66 user_is_primary_(false) {
67 // Do not observe shell, if there is no shell instance; e.g., in some unit
69 if (ash::Shell::HasInstance())
70 ash::Shell::GetInstance()->AddShellObserver(this);
73 Preferences::~Preferences() {
74 prefs_
->RemoveObserver(this);
75 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
76 // If shell instance is destoryed before this preferences instance, there is
77 // no need to remove this shell observer.
78 if (ash::Shell::HasInstance())
79 ash::Shell::GetInstance()->RemoveShellObserver(this);
83 void Preferences::RegisterPrefs(PrefRegistrySimple
* registry
) {
84 registry
->RegisterBooleanPref(prefs::kOwnerPrimaryMouseButtonRight
, false);
85 registry
->RegisterBooleanPref(prefs::kOwnerTapToClickEnabled
, true);
86 registry
->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled
,
88 registry
->RegisterStringPref(prefs::kLogoutStartedLast
, std::string());
92 void Preferences::RegisterProfilePrefs(
93 user_prefs::PrefRegistrySyncable
* registry
) {
94 std::string hardware_keyboard_id
;
95 // TODO(yusukes): Remove the runtime hack.
96 if (base::SysInfo::IsRunningOnChromeOS()) {
97 DCHECK(g_browser_process
);
98 PrefService
* local_state
= g_browser_process
->local_state();
100 hardware_keyboard_id
=
101 local_state
->GetString(prefs::kHardwareKeyboardLayout
);
103 hardware_keyboard_id
= "xkb:us::eng"; // only for testing.
106 registry
->RegisterBooleanPref(
107 prefs::kPerformanceTracingEnabled
,
109 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
111 registry
->RegisterBooleanPref(
112 prefs::kTapToClickEnabled
,
114 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
115 registry
->RegisterBooleanPref(
116 prefs::kTapDraggingEnabled
,
118 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
119 registry
->RegisterBooleanPref(
120 prefs::kEnableTouchpadThreeFingerClick
,
122 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
123 registry
->RegisterBooleanPref(
124 prefs::kNaturalScroll
,
125 CommandLine::ForCurrentProcess()->HasSwitch(
126 switches::kNaturalScrollDefault
),
127 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
128 registry
->RegisterBooleanPref(
129 prefs::kPrimaryMouseButtonRight
,
131 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
132 registry
->RegisterBooleanPref(
133 prefs::kLabsMediaplayerEnabled
,
135 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
136 registry
->RegisterBooleanPref(
137 prefs::kLabsAdvancedFilesystemEnabled
,
139 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
140 registry
->RegisterBooleanPref(
141 prefs::kAccessibilityStickyKeysEnabled
,
143 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
144 registry
->RegisterBooleanPref(
145 prefs::kAccessibilityLargeCursorEnabled
,
147 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
148 registry
->RegisterBooleanPref(
149 prefs::kAccessibilitySpokenFeedbackEnabled
,
151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
152 registry
->RegisterBooleanPref(
153 prefs::kAccessibilityHighContrastEnabled
,
155 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
156 registry
->RegisterBooleanPref(
157 prefs::kAccessibilityScreenMagnifierEnabled
,
159 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
160 registry
->RegisterIntegerPref(
161 prefs::kAccessibilityScreenMagnifierType
,
162 ui::kDefaultMagnifierType
,
163 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
164 registry
->RegisterDoublePref(
165 prefs::kAccessibilityScreenMagnifierScale
,
166 std::numeric_limits
<double>::min(),
167 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
168 registry
->RegisterBooleanPref(
169 prefs::kAccessibilityAutoclickEnabled
,
171 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
172 registry
->RegisterIntegerPref(
173 prefs::kAccessibilityAutoclickDelayMs
,
174 ash::AutoclickController::kDefaultAutoclickDelayMs
,
175 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
176 registry
->RegisterBooleanPref(
177 prefs::kAccessibilityVirtualKeyboardEnabled
,
179 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
180 registry
->RegisterBooleanPref(
181 prefs::kShouldAlwaysShowAccessibilityMenu
,
183 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
184 registry
->RegisterIntegerPref(
185 prefs::kMouseSensitivity
,
187 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
188 registry
->RegisterIntegerPref(
189 prefs::kTouchpadSensitivity
,
191 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
);
192 registry
->RegisterBooleanPref(
193 prefs::kUse24HourClock
,
194 base::GetHourClockType() == base::k24HourClock
,
195 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
196 registry
->RegisterBooleanPref(
197 prefs::kDisableDrive
,
199 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
200 registry
->RegisterBooleanPref(
201 prefs::kDisableDriveOverCellular
,
203 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
204 registry
->RegisterBooleanPref(
205 prefs::kDisableDriveHostedFiles
,
207 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
208 // We don't sync prefs::kLanguageCurrentInputMethod and PreviousInputMethod
209 // because they're just used to track the logout state of the device.
210 registry
->RegisterStringPref(
211 prefs::kLanguageCurrentInputMethod
,
213 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
214 registry
->RegisterStringPref(
215 prefs::kLanguagePreviousInputMethod
,
217 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
218 // We don't sync the list of input methods and preferred languages since a
219 // user might use two or more devices with different hardware keyboards.
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 // Mobile plan notifications default to on.
278 registry
->RegisterBooleanPref(
279 prefs::kShowPlanNotifications
,
281 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
283 // 3G first-time usage promo will be shown at least once.
284 registry
->RegisterBooleanPref(
285 prefs::kShow3gPromoNotification
,
287 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
289 // Initially all existing users would see "What's new" for current version
291 registry
->RegisterStringPref(prefs::kChromeOSReleaseNotesVersion
,
293 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
295 registry
->RegisterBooleanPref(
296 prefs::kExternalStorageDisabled
,
298 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
300 registry
->RegisterStringPref(
301 prefs::kTermsOfServiceURL
,
303 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
305 registry
->RegisterBooleanPref(
306 prefs::kTouchHudProjectionEnabled
,
308 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
310 registry
->RegisterBooleanPref(
311 prefs::kTouchVirtualKeyboardEnabled
,
313 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
316 void Preferences::InitUserPrefs(PrefServiceSyncable
* prefs
) {
319 BooleanPrefMember::NamedChangeCallback callback
=
320 base::Bind(&Preferences::OnPreferenceChanged
, base::Unretained(this));
322 performance_tracing_enabled_
.Init(prefs::kPerformanceTracingEnabled
,
324 tap_to_click_enabled_
.Init(prefs::kTapToClickEnabled
, prefs
, callback
);
325 tap_dragging_enabled_
.Init(prefs::kTapDraggingEnabled
, prefs
, callback
);
326 three_finger_click_enabled_
.Init(prefs::kEnableTouchpadThreeFingerClick
,
328 natural_scroll_
.Init(prefs::kNaturalScroll
, prefs
, callback
);
329 mouse_sensitivity_
.Init(prefs::kMouseSensitivity
, prefs
, callback
);
330 touchpad_sensitivity_
.Init(prefs::kTouchpadSensitivity
, prefs
, callback
);
331 primary_mouse_button_right_
.Init(prefs::kPrimaryMouseButtonRight
,
333 download_default_directory_
.Init(prefs::kDownloadDefaultDirectory
,
335 touch_hud_projection_enabled_
.Init(prefs::kTouchHudProjectionEnabled
,
337 preload_engines_
.Init(prefs::kLanguagePreloadEngines
, prefs
, callback
);
338 enabled_extension_imes_
.Init(prefs::kLanguageEnabledExtensionImes
,
340 current_input_method_
.Init(prefs::kLanguageCurrentInputMethod
,
342 previous_input_method_
.Init(prefs::kLanguagePreviousInputMethod
,
345 xkb_auto_repeat_enabled_
.Init(
346 prefs::kLanguageXkbAutoRepeatEnabled
, prefs
, callback
);
347 xkb_auto_repeat_delay_pref_
.Init(
348 prefs::kLanguageXkbAutoRepeatDelay
, prefs
, callback
);
349 xkb_auto_repeat_interval_pref_
.Init(
350 prefs::kLanguageXkbAutoRepeatInterval
, prefs
, callback
);
353 void Preferences::Init(Profile
* profile
, const user_manager::User
* user
) {
356 PrefServiceSyncable
* prefs
= PrefServiceSyncable::FromProfile(profile
);
359 user_manager::UserManager::Get()->GetPrimaryUser() == user_
;
360 InitUserPrefs(prefs
);
362 user_manager::UserManager::Get()->AddSessionStateObserver(this);
364 // This causes OnIsSyncingChanged to be called when the value of
365 // PrefService::IsSyncing() changes.
366 prefs
->AddObserver(this);
368 UserSessionManager
* session_manager
= UserSessionManager::GetInstance();
369 DCHECK(session_manager
);
370 ime_state_
= session_manager
->GetDefaultIMEState(profile
);
371 input_method_manager_
->SetState(ime_state_
);
373 // Initialize preferences to currently saved state.
374 ApplyPreferences(REASON_INITIALIZATION
, "");
376 // If a guest is logged in, initialize the prefs as if this is the first
377 // login. For a regular user this is done in
378 // UserSessionManager::InitProfilePreferences().
379 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession
))
380 session_manager
->SetFirstLoginPrefs(profile
, std::string(), std::string());
383 void Preferences::InitUserPrefsForTesting(
384 PrefServiceSyncable
* prefs
,
385 const user_manager::User
* user
,
386 scoped_refptr
<input_method::InputMethodManager::State
> ime_state
) {
388 ime_state_
= ime_state
;
391 input_method_manager_
->SetState(ime_state
);
393 InitUserPrefs(prefs
);
396 void Preferences::SetInputMethodListForTesting() {
397 SetInputMethodList();
400 void Preferences::OnPreferenceChanged(const std::string
& pref_name
) {
401 ApplyPreferences(REASON_PREF_CHANGED
, pref_name
);
404 void Preferences::ApplyPreferences(ApplyReason reason
,
405 const std::string
& pref_name
) {
406 DCHECK(reason
!= REASON_PREF_CHANGED
|| !pref_name
.empty());
407 const bool user_is_owner
=
408 user_manager::UserManager::Get()->GetOwnerEmail() == user_
->email();
409 const bool user_is_active
= user_
->is_active();
411 system::TouchpadSettings touchpad_settings
;
412 system::MouseSettings mouse_settings
;
414 if (user_is_primary_
&& (reason
== REASON_INITIALIZATION
||
415 pref_name
== prefs::kPerformanceTracingEnabled
)) {
416 const bool enabled
= performance_tracing_enabled_
.GetValue();
418 tracing_manager_
= TracingManager::Create();
420 tracing_manager_
.reset();
422 if (reason
!= REASON_PREF_CHANGED
|| pref_name
== prefs::kTapToClickEnabled
) {
423 const bool enabled
= tap_to_click_enabled_
.GetValue();
425 touchpad_settings
.SetTapToClick(enabled
);
426 if (reason
== REASON_PREF_CHANGED
)
427 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Changed", enabled
);
428 else if (reason
== REASON_INITIALIZATION
)
429 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Started", enabled
);
431 // Save owner preference in local state to use on login screen.
433 PrefService
* prefs
= g_browser_process
->local_state();
434 if (prefs
->GetBoolean(prefs::kOwnerTapToClickEnabled
) != enabled
)
435 prefs
->SetBoolean(prefs::kOwnerTapToClickEnabled
, enabled
);
438 if (reason
!= REASON_PREF_CHANGED
||
439 pref_name
== prefs::kTapDraggingEnabled
) {
440 const bool enabled
= tap_dragging_enabled_
.GetValue();
442 touchpad_settings
.SetTapDragging(enabled
);
443 if (reason
== REASON_PREF_CHANGED
)
444 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Changed", enabled
);
445 else if (reason
== REASON_INITIALIZATION
)
446 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Started", enabled
);
448 if (reason
!= REASON_PREF_CHANGED
||
449 pref_name
== prefs::kEnableTouchpadThreeFingerClick
) {
450 const bool enabled
= three_finger_click_enabled_
.GetValue();
452 touchpad_settings
.SetThreeFingerClick(enabled
);
453 if (reason
== REASON_PREF_CHANGED
)
454 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Changed", enabled
);
455 else if (reason
== REASON_INITIALIZATION
)
456 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Started", enabled
);
458 if (reason
!= REASON_PREF_CHANGED
|| pref_name
== prefs::kNaturalScroll
) {
459 // Force natural scroll default if we've sync'd and if the cmd line arg is
461 ForceNaturalScrollDefault();
463 const bool enabled
= natural_scroll_
.GetValue();
464 DVLOG(1) << "Natural scroll set to " << enabled
;
466 touchpad_settings
.SetNaturalScroll(enabled
);
467 if (reason
== REASON_PREF_CHANGED
)
468 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Changed", enabled
);
469 else if (reason
== REASON_INITIALIZATION
)
470 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Started", enabled
);
472 if (reason
!= REASON_PREF_CHANGED
|| pref_name
== prefs::kMouseSensitivity
) {
473 const int sensitivity
= mouse_sensitivity_
.GetValue();
475 mouse_settings
.SetSensitivity(sensitivity
);
476 if (reason
== REASON_PREF_CHANGED
) {
477 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Changed",
479 system::kMaxPointerSensitivity
+ 1);
480 } else if (reason
== REASON_INITIALIZATION
) {
481 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Started",
483 system::kMaxPointerSensitivity
+ 1);
486 if (reason
!= REASON_PREF_CHANGED
||
487 pref_name
== prefs::kTouchpadSensitivity
) {
488 const int sensitivity
= touchpad_sensitivity_
.GetValue();
490 touchpad_settings
.SetSensitivity(sensitivity
);
491 if (reason
== REASON_PREF_CHANGED
) {
492 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Changed",
494 system::kMaxPointerSensitivity
+ 1);
495 } else if (reason
== REASON_INITIALIZATION
) {
496 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Started",
498 system::kMaxPointerSensitivity
+ 1);
501 if (reason
!= REASON_PREF_CHANGED
||
502 pref_name
== prefs::kPrimaryMouseButtonRight
) {
503 const bool right
= primary_mouse_button_right_
.GetValue();
505 mouse_settings
.SetPrimaryButtonRight(right
);
506 if (reason
== REASON_PREF_CHANGED
)
507 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Changed", right
);
508 else if (reason
== REASON_INITIALIZATION
)
509 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Started", right
);
510 // Save owner preference in local state to use on login screen.
512 PrefService
* prefs
= g_browser_process
->local_state();
513 if (prefs
->GetBoolean(prefs::kOwnerPrimaryMouseButtonRight
) != right
)
514 prefs
->SetBoolean(prefs::kOwnerPrimaryMouseButtonRight
, right
);
517 if (reason
!= REASON_PREF_CHANGED
||
518 pref_name
== prefs::kDownloadDefaultDirectory
) {
519 const bool default_download_to_drive
= drive::util::IsUnderDriveMountPoint(
520 download_default_directory_
.GetValue());
521 if (reason
== REASON_PREF_CHANGED
)
522 UMA_HISTOGRAM_BOOLEAN(
523 "FileBrowser.DownloadDestination.IsGoogleDrive.Changed",
524 default_download_to_drive
);
525 else if (reason
== REASON_INITIALIZATION
)
526 UMA_HISTOGRAM_BOOLEAN(
527 "FileBrowser.DownloadDestination.IsGoogleDrive.Started",
528 default_download_to_drive
);
530 if (reason
!= REASON_PREF_CHANGED
||
531 pref_name
== prefs::kTouchHudProjectionEnabled
) {
532 #if !defined(USE_ATHENA)
533 if (user_is_active
) {
534 const bool enabled
= touch_hud_projection_enabled_
.GetValue();
535 ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled
);
540 if (reason
!= REASON_PREF_CHANGED
||
541 pref_name
== prefs::kLanguageXkbAutoRepeatEnabled
) {
542 if (user_is_active
) {
543 const bool enabled
= xkb_auto_repeat_enabled_
.GetValue();
544 input_method::InputMethodManager::Get()
546 ->SetAutoRepeatEnabled(enabled
);
549 if (reason
!= REASON_PREF_CHANGED
||
550 pref_name
== prefs::kLanguageXkbAutoRepeatDelay
||
551 pref_name
== prefs::kLanguageXkbAutoRepeatInterval
) {
553 UpdateAutoRepeatRate();
556 if (reason
== REASON_INITIALIZATION
)
557 SetInputMethodList();
559 if (pref_name
== prefs::kLanguagePreloadEngines
&&
560 reason
== REASON_PREF_CHANGED
) {
561 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName
,
562 language_prefs::kPreloadEnginesConfigName
,
563 preload_engines_
.GetValue());
566 if ((reason
== REASON_INITIALIZATION
) ||
567 (pref_name
== prefs::kLanguageEnabledExtensionImes
&&
568 reason
== REASON_PREF_CHANGED
)) {
569 std::string
value(enabled_extension_imes_
.GetValue());
571 std::vector
<std::string
> split_values
;
573 base::SplitString(value
, ',', &split_values
);
575 ime_state_
->SetEnabledExtensionImes(&split_values
);
578 if (user_is_active
) {
579 system::InputDeviceSettings::Get()->UpdateTouchpadSettings(
581 system::InputDeviceSettings::Get()->UpdateMouseSettings(mouse_settings
);
585 void Preferences::OnIsSyncingChanged() {
586 DVLOG(1) << "OnIsSyncingChanged";
587 ForceNaturalScrollDefault();
590 void Preferences::ForceNaturalScrollDefault() {
591 DVLOG(1) << "ForceNaturalScrollDefault";
592 if (CommandLine::ForCurrentProcess()->HasSwitch(
593 switches::kNaturalScrollDefault
) &&
594 prefs_
->IsSyncing() &&
595 !prefs_
->GetUserPrefValue(prefs::kNaturalScroll
)) {
596 DVLOG(1) << "Natural scroll forced to true";
597 natural_scroll_
.SetValue(true);
598 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Forced", true);
602 void Preferences::SetLanguageConfigStringListAsCSV(const char* section
,
604 const std::string
& value
) {
605 VLOG(1) << "Setting " << name
<< " to '" << value
<< "'";
607 std::vector
<std::string
> split_values
;
609 base::SplitString(value
, ',', &split_values
);
611 // Transfers the xkb id to extension-xkb id.
612 if (input_method_manager_
->MigrateInputMethods(&split_values
))
613 preload_engines_
.SetValue(JoinString(split_values
, ','));
615 if (section
== std::string(language_prefs::kGeneralSectionName
) &&
616 name
== std::string(language_prefs::kPreloadEnginesConfigName
)) {
617 ime_state_
->ReplaceEnabledInputMethods(split_values
);
622 void Preferences::SetInputMethodList() {
623 // When |preload_engines_| are set, InputMethodManager::ChangeInputMethod()
624 // might be called to change the current input method to the first one in the
625 // |preload_engines_| list. This also updates previous/current input method
626 // prefs. That's why GetValue() calls are placed before the
627 // SetLanguageConfigStringListAsCSV() call below.
628 const std::string previous_input_method_id
=
629 previous_input_method_
.GetValue();
630 const std::string current_input_method_id
= current_input_method_
.GetValue();
631 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName
,
632 language_prefs::kPreloadEnginesConfigName
,
633 preload_engines_
.GetValue());
635 // ChangeInputMethod() has to be called AFTER the value of |preload_engines_|
636 // is sent to the InputMethodManager. Otherwise, the ChangeInputMethod request
637 // might be ignored as an invalid input method ID. The ChangeInputMethod()
638 // calls are also necessary to restore the previous/current input method prefs
639 // which could have been modified by the SetLanguageConfigStringListAsCSV call
640 // above to the original state.
641 if (!previous_input_method_id
.empty())
642 ime_state_
->ChangeInputMethod(previous_input_method_id
,
643 false /* show_message */);
644 if (!current_input_method_id
.empty())
645 ime_state_
->ChangeInputMethod(current_input_method_id
,
646 false /* show_message */);
649 void Preferences::UpdateAutoRepeatRate() {
650 input_method::AutoRepeatRate rate
;
651 rate
.initial_delay_in_ms
= xkb_auto_repeat_delay_pref_
.GetValue();
652 rate
.repeat_interval_in_ms
= xkb_auto_repeat_interval_pref_
.GetValue();
653 DCHECK(rate
.initial_delay_in_ms
> 0);
654 DCHECK(rate
.repeat_interval_in_ms
> 0);
655 input_method::InputMethodManager::Get()
657 ->SetAutoRepeatRate(rate
);
660 void Preferences::OnTouchHudProjectionToggled(bool enabled
) {
661 if (touch_hud_projection_enabled_
.GetValue() == enabled
)
663 if (!user_
->is_active())
665 touch_hud_projection_enabled_
.SetValue(enabled
);
668 void Preferences::ActiveUserChanged(const user_manager::User
* active_user
) {
669 if (active_user
!= user_
)
671 ApplyPreferences(REASON_ACTIVE_USER_CHANGED
, "");
674 } // namespace chromeos