1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/preferences.h" 6 7 #include "ash/autoclick/autoclick_controller.h" 8 #include "ash/magnifier/magnifier_constants.h" 9 #include "ash/shell.h" 10 #include "base/command_line.h" 11 #include "base/i18n/time_formatting.h" 12 #include "base/metrics/histogram.h" 13 #include "base/prefs/pref_member.h" 14 #include "base/prefs/pref_registry_simple.h" 15 #include "base/prefs/scoped_user_pref_update.h" 16 #include "base/strings/string_split.h" 17 #include "base/strings/string_util.h" 18 #include "base/strings/utf_string_conversions.h" 19 #include "base/sys_info.h" 20 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/chrome_notification_types.h" 22 #include "chrome/browser/chromeos/accessibility/magnification_manager.h" 23 #include "chrome/browser/chromeos/drive/file_system_util.h" 24 #include "chrome/browser/chromeos/input_method/input_method_util.h" 25 #include "chrome/browser/chromeos/login/login_utils.h" 26 #include "chrome/browser/chromeos/login/user_manager.h" 27 #include "chrome/browser/chromeos/system/input_device_settings.h" 28 #include "chrome/browser/download/download_prefs.h" 29 #include "chrome/browser/feedback/tracing_manager.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/input_method_manager.h" 35 #include "chromeos/ime/xkeyboard.h" 36 #include "chromeos/system/statistics_provider.h" 37 #include "components/user_prefs/pref_registry_syncable.h" 38 #include "third_party/icu/source/i18n/unicode/timezone.h" 39 #include "ui/events/event_constants.h" 40 #include "ui/events/event_utils.h" 41 #include "url/gurl.h" 42 43 namespace chromeos { 44 45 static const char kFallbackInputMethodLocale[] = "en-US"; 46 47 // TODO(achuith): Remove deprecated pref in M31. crbug.com/223480. 48 static const char kEnableTouchpadThreeFingerSwipe[] = 49 "settings.touchpad.enable_three_finger_swipe"; 50 51 Preferences::Preferences() 52 : prefs_(NULL), 53 input_method_manager_(input_method::InputMethodManager::Get()), 54 is_primary_user_prefs_(true) { 55 // Do not observe shell, if there is no shell instance; e.g., in some unit 56 // tests. 57 if (ash::Shell::HasInstance()) 58 ash::Shell::GetInstance()->AddShellObserver(this); 59 } 60 61 Preferences::Preferences(input_method::InputMethodManager* input_method_manager) 62 : prefs_(NULL), 63 input_method_manager_(input_method_manager), 64 is_primary_user_prefs_(true) { 65 // Do not observe shell, if there is no shell instance; e.g., in some unit 66 // tests. 67 if (ash::Shell::HasInstance()) 68 ash::Shell::GetInstance()->AddShellObserver(this); 69 } 70 71 Preferences::~Preferences() { 72 prefs_->RemoveObserver(this); 73 // If shell instance is destoryed before this preferences instance, there is 74 // no need to remove this shell observer. 75 if (ash::Shell::HasInstance()) 76 ash::Shell::GetInstance()->RemoveShellObserver(this); 77 } 78 79 // static 80 void Preferences::RegisterPrefs(PrefRegistrySimple* registry) { 81 registry->RegisterBooleanPref(prefs::kOwnerPrimaryMouseButtonRight, false); 82 registry->RegisterBooleanPref(prefs::kOwnerTapToClickEnabled, true); 83 registry->RegisterBooleanPref(prefs::kVirtualKeyboardEnabled, false); 84 } 85 86 // static 87 void Preferences::RegisterProfilePrefs( 88 user_prefs::PrefRegistrySyncable* registry) { 89 std::string hardware_keyboard_id; 90 // TODO(yusukes): Remove the runtime hack. 91 if (base::SysInfo::IsRunningOnChromeOS()) { 92 input_method::InputMethodManager* manager = 93 input_method::InputMethodManager::Get(); 94 if (manager) { 95 hardware_keyboard_id = 96 manager->GetInputMethodUtil()->GetHardwareInputMethodId(); 97 } 98 } else { 99 hardware_keyboard_id = "xkb:us::eng"; // only for testing. 100 } 101 102 registry->RegisterBooleanPref( 103 prefs::kPerformanceTracingEnabled, 104 false, 105 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 106 107 registry->RegisterBooleanPref( 108 prefs::kTapToClickEnabled, 109 true, 110 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 111 registry->RegisterBooleanPref( 112 prefs::kTapDraggingEnabled, 113 false, 114 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 115 registry->RegisterBooleanPref( 116 prefs::kEnableTouchpadThreeFingerClick, 117 false, 118 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 119 registry->RegisterBooleanPref( 120 prefs::kNaturalScroll, 121 CommandLine::ForCurrentProcess()->HasSwitch( 122 switches::kNaturalScrollDefault), 123 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 124 registry->RegisterBooleanPref( 125 prefs::kPrimaryMouseButtonRight, 126 false, 127 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 128 registry->RegisterBooleanPref( 129 prefs::kLabsMediaplayerEnabled, 130 false, 131 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 132 registry->RegisterBooleanPref( 133 prefs::kLabsAdvancedFilesystemEnabled, 134 false, 135 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 136 registry->RegisterBooleanPref( 137 prefs::kStickyKeysEnabled, 138 false, 139 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 140 registry->RegisterBooleanPref( 141 prefs::kLargeCursorEnabled, 142 false, 143 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 144 registry->RegisterBooleanPref( 145 prefs::kSpokenFeedbackEnabled, 146 false, 147 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 148 registry->RegisterBooleanPref( 149 prefs::kHighContrastEnabled, 150 false, 151 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 152 registry->RegisterBooleanPref( 153 prefs::kScreenMagnifierEnabled, 154 false, 155 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 156 registry->RegisterIntegerPref( 157 prefs::kScreenMagnifierType, 158 ash::kDefaultMagnifierType, 159 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 160 registry->RegisterDoublePref( 161 prefs::kScreenMagnifierScale, 162 std::numeric_limits<double>::min(), 163 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 164 registry->RegisterBooleanPref( 165 prefs::kAutoclickEnabled, 166 false, 167 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 168 registry->RegisterIntegerPref( 169 prefs::kAutoclickDelayMs, 170 ash::AutoclickController::kDefaultAutoclickDelayMs, 171 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 172 registry->RegisterBooleanPref( 173 prefs::kShouldAlwaysShowAccessibilityMenu, 174 false, 175 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 176 registry->RegisterIntegerPref( 177 prefs::kMouseSensitivity, 178 3, 179 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 180 registry->RegisterIntegerPref( 181 prefs::kTouchpadSensitivity, 182 3, 183 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 184 registry->RegisterBooleanPref( 185 prefs::kUse24HourClock, 186 base::GetHourClockType() == base::k24HourClock, 187 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 188 registry->RegisterBooleanPref( 189 prefs::kDisableDrive, 190 false, 191 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 192 registry->RegisterBooleanPref( 193 prefs::kDisableDriveOverCellular, 194 true, 195 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 196 registry->RegisterBooleanPref( 197 prefs::kDisableDriveHostedFiles, 198 false, 199 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 200 // We don't sync prefs::kLanguageCurrentInputMethod and PreviousInputMethod 201 // because they're just used to track the logout state of the device. 202 registry->RegisterStringPref( 203 prefs::kLanguageCurrentInputMethod, 204 "", 205 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 206 registry->RegisterStringPref( 207 prefs::kLanguagePreviousInputMethod, 208 "", 209 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 210 // We don't sync the list of input methods and preferred languages since a 211 // user might use two or more devices with different hardware keyboards. 212 // crosbug.com/15181 213 registry->RegisterStringPref( 214 prefs::kLanguagePreferredLanguages, 215 kFallbackInputMethodLocale, 216 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 217 registry->RegisterStringPref( 218 prefs::kLanguagePreloadEngines, 219 hardware_keyboard_id, 220 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 221 registry->RegisterStringPref( 222 prefs::kLanguageEnabledExtensionImes, 223 "", 224 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 225 226 registry->RegisterIntegerPref( 227 prefs::kLanguageRemapSearchKeyTo, 228 input_method::kSearchKey, 229 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 230 registry->RegisterIntegerPref( 231 prefs::kLanguageRemapControlKeyTo, 232 input_method::kControlKey, 233 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 234 registry->RegisterIntegerPref( 235 prefs::kLanguageRemapAltKeyTo, 236 input_method::kAltKey, 237 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 238 // We don't sync the CapsLock remapping pref, since the UI hides this pref 239 // on certain devices, so syncing a non-default value to a device that 240 // doesn't allow changing the pref would be odd. http://crbug.com/167237 241 registry->RegisterIntegerPref( 242 prefs::kLanguageRemapCapsLockKeyTo, 243 input_method::kCapsLockKey, 244 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 245 registry->RegisterIntegerPref( 246 prefs::kLanguageRemapDiamondKeyTo, 247 input_method::kControlKey, 248 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); 249 // The following pref isn't synced since the user may desire a different value 250 // depending on whether an external keyboard is attached to a particular 251 // device. 252 registry->RegisterBooleanPref( 253 prefs::kLanguageSendFunctionKeys, 254 false, 255 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 256 // We don't sync the following keyboard prefs since they are not user- 257 // configurable. 258 registry->RegisterBooleanPref( 259 prefs::kLanguageXkbAutoRepeatEnabled, 260 true, 261 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 262 registry->RegisterIntegerPref( 263 prefs::kLanguageXkbAutoRepeatDelay, 264 language_prefs::kXkbAutoRepeatDelayInMs, 265 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 266 registry->RegisterIntegerPref( 267 prefs::kLanguageXkbAutoRepeatInterval, 268 language_prefs::kXkbAutoRepeatIntervalInMs, 269 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 270 271 // Mobile plan notifications default to on. 272 registry->RegisterBooleanPref( 273 prefs::kShowPlanNotifications, 274 true, 275 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 276 277 // 3G first-time usage promo will be shown at least once. 278 registry->RegisterBooleanPref( 279 prefs::kShow3gPromoNotification, 280 true, 281 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 282 283 // Initially all existing users would see "What's new" for current version 284 // after update. 285 registry->RegisterStringPref(prefs::kChromeOSReleaseNotesVersion, 286 "0.0.0.0", 287 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 288 289 registry->RegisterBooleanPref( 290 prefs::kExternalStorageDisabled, 291 false, 292 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 293 294 registry->RegisterStringPref( 295 prefs::kTermsOfServiceURL, 296 "", 297 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 298 299 // TODO(achuith): Remove deprecated pref in M31. crbug.com/223480. 300 registry->RegisterBooleanPref( 301 kEnableTouchpadThreeFingerSwipe, 302 false, 303 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 304 305 registry->RegisterBooleanPref( 306 prefs::kTouchHudProjectionEnabled, 307 false, 308 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 309 } 310 311 void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) { 312 prefs_ = prefs; 313 314 BooleanPrefMember::NamedChangeCallback callback = 315 base::Bind(&Preferences::OnPreferenceChanged, base::Unretained(this)); 316 317 performance_tracing_enabled_.Init(prefs::kPerformanceTracingEnabled, 318 prefs, callback); 319 tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, callback); 320 tap_dragging_enabled_.Init(prefs::kTapDraggingEnabled, prefs, callback); 321 three_finger_click_enabled_.Init(prefs::kEnableTouchpadThreeFingerClick, 322 prefs, callback); 323 natural_scroll_.Init(prefs::kNaturalScroll, prefs, callback); 324 a11y_spoken_feedback_enabled_.Init(prefs::kSpokenFeedbackEnabled, 325 prefs, callback); 326 a11y_high_contrast_enabled_.Init(prefs::kHighContrastEnabled, 327 prefs, callback); 328 a11y_screen_magnifier_enabled_.Init(prefs::kScreenMagnifierEnabled, 329 prefs, callback); 330 a11y_screen_magnifier_type_.Init(prefs::kScreenMagnifierType, 331 prefs, callback); 332 a11y_screen_magnifier_scale_.Init(prefs::kScreenMagnifierScale, 333 prefs, callback); 334 mouse_sensitivity_.Init(prefs::kMouseSensitivity, prefs, callback); 335 touchpad_sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, callback); 336 use_24hour_clock_.Init(prefs::kUse24HourClock, prefs, callback); 337 disable_drive_.Init(prefs::kDisableDrive, prefs, callback); 338 disable_drive_over_cellular_.Init(prefs::kDisableDriveOverCellular, 339 prefs, callback); 340 disable_drive_hosted_files_.Init(prefs::kDisableDriveHostedFiles, 341 prefs, callback); 342 download_default_directory_.Init(prefs::kDownloadDefaultDirectory, 343 prefs, callback); 344 select_file_last_directory_.Init(prefs::kSelectFileLastDirectory, 345 prefs, callback); 346 save_file_default_directory_.Init(prefs::kSaveFileDefaultDirectory, 347 prefs, callback); 348 touch_hud_projection_enabled_.Init(prefs::kTouchHudProjectionEnabled, 349 prefs, callback); 350 primary_mouse_button_right_.Init(prefs::kPrimaryMouseButtonRight, 351 prefs, callback); 352 preferred_languages_.Init(prefs::kLanguagePreferredLanguages, 353 prefs, callback); 354 preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, callback); 355 enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes, 356 prefs, callback); 357 current_input_method_.Init(prefs::kLanguageCurrentInputMethod, 358 prefs, callback); 359 previous_input_method_.Init(prefs::kLanguagePreviousInputMethod, 360 prefs, callback); 361 362 xkb_auto_repeat_enabled_.Init( 363 prefs::kLanguageXkbAutoRepeatEnabled, prefs, callback); 364 xkb_auto_repeat_delay_pref_.Init( 365 prefs::kLanguageXkbAutoRepeatDelay, prefs, callback); 366 xkb_auto_repeat_interval_pref_.Init( 367 prefs::kLanguageXkbAutoRepeatInterval, prefs, callback); 368 369 // TODO(achuith): Remove deprecated pref in M31. crbug.com/223480. 370 prefs->ClearPref(kEnableTouchpadThreeFingerSwipe); 371 } 372 373 void Preferences::Init(PrefServiceSyncable* prefs, bool is_primary_user) { 374 is_primary_user_prefs_ = is_primary_user; 375 InitUserPrefs(prefs); 376 377 // This causes OnIsSyncingChanged to be called when the value of 378 // PrefService::IsSyncing() changes. 379 prefs->AddObserver(this); 380 381 // Initialize preferences to currently saved state. 382 NotifyPrefChanged(NULL); 383 384 // If a guest is logged in, initialize the prefs as if this is the first 385 // login. 386 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) { 387 LoginUtils::Get()->SetFirstLoginPrefs(prefs); 388 } 389 } 390 391 void Preferences::InitUserPrefsForTesting(PrefServiceSyncable* prefs) { 392 InitUserPrefs(prefs); 393 } 394 395 void Preferences::SetInputMethodListForTesting() { 396 SetInputMethodList(); 397 } 398 399 void Preferences::OnPreferenceChanged(const std::string& pref_name) { 400 NotifyPrefChanged(&pref_name); 401 } 402 403 void Preferences::NotifyPrefChanged(const std::string* pref_name) { 404 if (!pref_name || *pref_name == prefs::kPerformanceTracingEnabled) { 405 const bool enabled = performance_tracing_enabled_.GetValue(); 406 if (enabled) 407 tracing_manager_ = TracingManager::Create(); 408 else 409 tracing_manager_.reset(); 410 } 411 if ((!pref_name && is_primary_user_prefs_) || 412 (pref_name && *pref_name == prefs::kTapToClickEnabled)) { 413 const bool enabled = tap_to_click_enabled_.GetValue(); 414 system::touchpad_settings::SetTapToClick(enabled); 415 if (pref_name) 416 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Changed", enabled); 417 else 418 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Started", enabled); 419 420 // Save owner preference in local state to use on login screen. 421 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) { 422 PrefService* prefs = g_browser_process->local_state(); 423 if (prefs->GetBoolean(prefs::kOwnerTapToClickEnabled) != enabled) 424 prefs->SetBoolean(prefs::kOwnerTapToClickEnabled, enabled); 425 } 426 } 427 if ((!pref_name && is_primary_user_prefs_) || 428 (pref_name && *pref_name == prefs::kTapDraggingEnabled)) { 429 const bool enabled = tap_dragging_enabled_.GetValue(); 430 system::touchpad_settings::SetTapDragging(enabled); 431 if (pref_name) 432 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Changed", enabled); 433 else 434 UMA_HISTOGRAM_BOOLEAN("Touchpad.TapDragging.Started", enabled); 435 } 436 if ((!pref_name && is_primary_user_prefs_) || 437 (pref_name && *pref_name == prefs::kEnableTouchpadThreeFingerClick)) { 438 const bool enabled = three_finger_click_enabled_.GetValue(); 439 system::touchpad_settings::SetThreeFingerClick(enabled); 440 if (pref_name) 441 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Changed", enabled); 442 else 443 UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Started", enabled); 444 } 445 if ((!pref_name && is_primary_user_prefs_) || 446 (pref_name && *pref_name == prefs::kNaturalScroll)) { 447 // Force natural scroll default if we've sync'd and if the cmd line arg is 448 // set. 449 ForceNaturalScrollDefault(); 450 451 const bool enabled = natural_scroll_.GetValue(); 452 DVLOG(1) << "Natural scroll set to " << enabled; 453 ui::SetNaturalScroll(enabled); 454 if (pref_name) 455 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Changed", enabled); 456 else 457 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Started", enabled); 458 } 459 if ((!pref_name && is_primary_user_prefs_) || 460 (pref_name && *pref_name == prefs::kMouseSensitivity)) { 461 const int sensitivity = mouse_sensitivity_.GetValue(); 462 system::mouse_settings::SetSensitivity(sensitivity); 463 if (pref_name) { 464 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Changed", 465 sensitivity, 466 system::kMaxPointerSensitivity + 1); 467 } else { 468 UMA_HISTOGRAM_ENUMERATION("Mouse.PointerSensitivity.Started", 469 sensitivity, 470 system::kMaxPointerSensitivity + 1); 471 } 472 } 473 if ((!pref_name && is_primary_user_prefs_) || 474 (pref_name && *pref_name == prefs::kTouchpadSensitivity)) { 475 const int sensitivity = touchpad_sensitivity_.GetValue(); 476 system::touchpad_settings::SetSensitivity(sensitivity); 477 if (pref_name) { 478 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Changed", 479 sensitivity, 480 system::kMaxPointerSensitivity + 1); 481 } else { 482 UMA_HISTOGRAM_ENUMERATION("Touchpad.PointerSensitivity.Started", 483 sensitivity, 484 system::kMaxPointerSensitivity + 1); 485 } 486 } 487 if ((!pref_name && is_primary_user_prefs_) || 488 (pref_name && *pref_name == prefs::kPrimaryMouseButtonRight)) { 489 const bool right = primary_mouse_button_right_.GetValue(); 490 system::mouse_settings::SetPrimaryButtonRight(right); 491 if (pref_name) 492 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Changed", right); 493 else 494 UMA_HISTOGRAM_BOOLEAN("Mouse.PrimaryButtonRight.Started", right); 495 496 // Save owner preference in local state to use on login screen. 497 if (chromeos::UserManager::Get()->IsCurrentUserOwner()) { 498 PrefService* prefs = g_browser_process->local_state(); 499 if (prefs->GetBoolean(prefs::kOwnerPrimaryMouseButtonRight) != right) 500 prefs->SetBoolean(prefs::kOwnerPrimaryMouseButtonRight, right); 501 } 502 } 503 if (!pref_name || *pref_name == prefs::kDownloadDefaultDirectory) { 504 const bool default_download_to_drive = drive::util::IsUnderDriveMountPoint( 505 download_default_directory_.GetValue()); 506 if (pref_name) 507 UMA_HISTOGRAM_BOOLEAN( 508 "FileBrowser.DownloadDestination.IsGoogleDrive.Changed", 509 default_download_to_drive); 510 else 511 UMA_HISTOGRAM_BOOLEAN( 512 "FileBrowser.DownloadDestination.IsGoogleDrive.Started", 513 default_download_to_drive); 514 } 515 if ((!pref_name && is_primary_user_prefs_) || 516 (pref_name && *pref_name == prefs::kTouchHudProjectionEnabled)) { 517 const bool enabled = touch_hud_projection_enabled_.GetValue(); 518 ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled); 519 } 520 521 if (!pref_name || *pref_name == prefs::kLanguagePreferredLanguages) { 522 // Unlike kLanguagePreloadEngines and some other input method 523 // preferencs, we don't need to send this to ibus-daemon. 524 } 525 526 if (!pref_name || *pref_name == prefs::kLanguageXkbAutoRepeatEnabled) { 527 const bool enabled = xkb_auto_repeat_enabled_.GetValue(); 528 input_method::XKeyboard::SetAutoRepeatEnabled(enabled); 529 } 530 if (!pref_name || ((*pref_name == prefs::kLanguageXkbAutoRepeatDelay) || 531 (*pref_name == prefs::kLanguageXkbAutoRepeatInterval))) { 532 UpdateAutoRepeatRate(); 533 } 534 535 if (!pref_name) { 536 SetInputMethodList(); 537 } else if (*pref_name == prefs::kLanguagePreloadEngines) { 538 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName, 539 language_prefs::kPreloadEnginesConfigName, 540 preload_engines_.GetValue()); 541 } 542 543 if (!pref_name || *pref_name == prefs::kLanguageEnabledExtensionImes) { 544 std::string value(enabled_extension_imes_.GetValue()); 545 546 std::vector<std::string> split_values; 547 if (!value.empty()) 548 base::SplitString(value, ',', &split_values); 549 550 input_method_manager_->SetEnabledExtensionImes(&split_values); 551 } 552 } 553 554 void Preferences::OnIsSyncingChanged() { 555 DVLOG(1) << "OnIsSyncingChanged"; 556 ForceNaturalScrollDefault(); 557 } 558 559 void Preferences::ForceNaturalScrollDefault() { 560 DVLOG(1) << "ForceNaturalScrollDefault"; 561 if (CommandLine::ForCurrentProcess()->HasSwitch( 562 switches::kNaturalScrollDefault) && 563 prefs_->IsSyncing() && 564 !prefs_->GetUserPrefValue(prefs::kNaturalScroll)) { 565 DVLOG(1) << "Natural scroll forced to true"; 566 natural_scroll_.SetValue(true); 567 UMA_HISTOGRAM_BOOLEAN("Touchpad.NaturalScroll.Forced", true); 568 } 569 } 570 571 void Preferences::SetLanguageConfigStringListAsCSV(const char* section, 572 const char* name, 573 const std::string& value) { 574 VLOG(1) << "Setting " << name << " to '" << value << "'"; 575 576 std::vector<std::string> split_values; 577 if (!value.empty()) 578 base::SplitString(value, ',', &split_values); 579 580 if (section == std::string(language_prefs::kGeneralSectionName) && 581 name == std::string(language_prefs::kPreloadEnginesConfigName)) { 582 input_method_manager_->EnableInputMethods(split_values); 583 return; 584 } 585 } 586 587 void Preferences::SetInputMethodList() { 588 // When |preload_engines_| are set, InputMethodManager::ChangeInputMethod() 589 // might be called to change the current input method to the first one in the 590 // |preload_engines_| list. This also updates previous/current input method 591 // prefs. That's why GetValue() calls are placed before the 592 // SetLanguageConfigStringListAsCSV() call below. 593 const std::string previous_input_method_id = 594 previous_input_method_.GetValue(); 595 const std::string current_input_method_id = current_input_method_.GetValue(); 596 SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName, 597 language_prefs::kPreloadEnginesConfigName, 598 preload_engines_.GetValue()); 599 600 // ChangeInputMethod() has to be called AFTER the value of |preload_engines_| 601 // is sent to the InputMethodManager. Otherwise, the ChangeInputMethod request 602 // might be ignored as an invalid input method ID. The ChangeInputMethod() 603 // calls are also necessary to restore the previous/current input method prefs 604 // which could have been modified by the SetLanguageConfigStringListAsCSV call 605 // above to the original state. 606 if (!previous_input_method_id.empty()) 607 input_method_manager_->ChangeInputMethod(previous_input_method_id); 608 if (!current_input_method_id.empty()) 609 input_method_manager_->ChangeInputMethod(current_input_method_id); 610 } 611 612 void Preferences::UpdateAutoRepeatRate() { 613 // Avoid setting repeat rate on desktop dev environment. 614 if (!base::SysInfo::IsRunningOnChromeOS()) 615 return; 616 617 input_method::AutoRepeatRate rate; 618 rate.initial_delay_in_ms = xkb_auto_repeat_delay_pref_.GetValue(); 619 rate.repeat_interval_in_ms = xkb_auto_repeat_interval_pref_.GetValue(); 620 DCHECK(rate.initial_delay_in_ms > 0); 621 DCHECK(rate.repeat_interval_in_ms > 0); 622 input_method::XKeyboard::SetAutoRepeatRate(rate); 623 } 624 625 void Preferences::OnTouchHudProjectionToggled(bool enabled) { 626 if (touch_hud_projection_enabled_.GetValue() == enabled) 627 return; 628 629 touch_hud_projection_enabled_.SetValue(enabled); 630 } 631 632 } // namespace chromeos 633