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