Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4499)

Unified Diff: chrome/browser/chromeos/preferences.cc

Issue 312023002: Sync starting language and input method preferences (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/preferences.cc
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index d0e04df2792ce1d2af8709b4bf1f57bad55f0e96..3bbff17074a2d2db822a8d7442454fd3f709c8c8 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -45,11 +45,49 @@
namespace chromeos {
+namespace {
+
static const char kFallbackInputMethodLocale[] = "en-US";
+// Returns a copy of |old_value| with any unique CSVs from |new_value|
+// appended, a logical union that retains order. Quadratic runtime; use only
+// for small lists.
michaelpg 2014/06/04 01:12:02 Why not use ListValues instead of StringValues for
+std::string MergeCSVs(const std::string& old_value,
+ const std::string& new_value) {
+ std::string merged;
+ std::vector<std::string> old_tokens;
+ std::vector<std::string> new_tokens;
+
+ base::SplitString(old_value, ',', &old_tokens);
+ base::SplitString(new_value, ',', &new_tokens);
+
+ for (size_t i = 0; i < new_tokens.size(); i++) {
+ // Skip token if it's already in |old_tokens|.
+ if (std::find(old_tokens.begin(), old_tokens.end(), new_tokens[i]) ==
+ old_tokens.end())
+ old_tokens.push_back(new_tokens[i]);
+ }
+ return JoinString(old_tokens, ',');
+}
+
+// Merges one CSV pref into another using MergeCSVs.
+void MergeStringPrefs(StringPrefMember& to_pref,
+ StringPrefMember& from_pref,
+ const std::string& pref_name) {
+ std::string to_value = to_pref.GetValue();
+ std::string from_value = from_pref.GetValue();
+
+ std::string merged_value = MergeCSVs(to_value, from_value);
+ if (merged_value != to_value)
+ to_pref.SetValue(merged_value);
+}
+
+} // anonymous namespace
+
Preferences::Preferences()
: prefs_(NULL),
input_method_manager_(input_method::InputMethodManager::Get()),
+ should_merge_locale_prefs_(false),
user_(NULL),
user_is_primary_(false) {
// Do not observe shell, if there is no shell instance; e.g., in some unit
@@ -61,6 +99,7 @@ Preferences::Preferences()
Preferences::Preferences(input_method::InputMethodManager* input_method_manager)
: prefs_(NULL),
input_method_manager_(input_method_manager),
+ should_merge_locale_prefs_(false),
user_(NULL),
user_is_primary_(false) {
// Do not observe shell, if there is no shell instance; e.g., in some unit
@@ -213,20 +252,29 @@ void Preferences::RegisterProfilePrefs(
prefs::kLanguagePreviousInputMethod,
"",
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
- // We don't sync the list of input methods and preferred languages since a
- // user might use two or more devices with different hardware keyboards.
- // crosbug.com/15181
registry->RegisterStringPref(
prefs::kLanguagePreferredLanguages,
+ "",
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+ registry->RegisterStringPref(
+ prefs::kLanguagePreferredLanguagesLocal,
Alexander Alekseev 2014/06/04 14:20:57 I think it is dangerous to change meaning of exist
kFallbackInputMethodLocale,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
registry->RegisterStringPref(
prefs::kLanguagePreloadEngines,
+ "",
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+ registry->RegisterStringPref(
+ prefs::kLanguagePreloadEnginesLocal,
Alexander Alekseev 2014/06/04 14:20:57 The same for engines.
hardware_keyboard_id,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
registry->RegisterStringPref(
prefs::kLanguageEnabledExtensionImes,
"",
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+ registry->RegisterStringPref(
+ prefs::kLanguageEnabledExtensionImesLocal,
+ "",
Alexander Alekseev 2014/06/04 14:20:57 The same for EnabledExtensionsImes
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
registry->RegisterIntegerPref(
@@ -329,9 +377,17 @@ void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) {
prefs, callback);
touch_hud_projection_enabled_.Init(prefs::kTouchHudProjectionEnabled,
prefs, callback);
+ preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
+ prefs, callback);
+ preferred_languages_local_.Init(prefs::kLanguagePreferredLanguagesLocal,
+ prefs, callback);
preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, callback);
+ preload_engines_local_.Init(prefs::kLanguagePreloadEnginesLocal,
+ prefs, callback);
enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes,
prefs, callback);
+ enabled_extension_imes_local_.Init(prefs::kLanguageEnabledExtensionImesLocal,
+ prefs, callback);
current_input_method_.Init(prefs::kLanguageCurrentInputMethod,
prefs, callback);
previous_input_method_.Init(prefs::kLanguagePreviousInputMethod,
@@ -388,6 +444,27 @@ void Preferences::ApplyPreferences(ApplyReason reason,
UserManager::Get()->GetOwnerEmail() == user_->email();
const bool user_is_active = user_->is_active();
+ if (reason == REASON_INITIALIZATION) {
+ // Check that the global language/input preferences have been set.
+ if (prefs_->FindPreference(prefs::kLanguagePreferredLanguages)->
+ HasUserSetting()) {
+ // If no local value has been set, this is a pre-existing profile.
+ if (!prefs_->FindPreference(prefs::kLanguagePreferredLanguagesLocal)->
+ HasUserSetting()) {
+ // Migrate to using local values by copying the global values.
+ preferred_languages_local_.SetValue(preferred_languages_.GetValue());
+ preload_engines_local_.SetValue(preload_engines_.GetValue());
Alexander Alekseev 2014/06/04 14:23:56 The same as my comment below: the list of supporte
+ enabled_extension_imes_local_.SetValue(
+ enabled_extension_imes_.GetValue());
Alexander Alekseev 2014/06/04 14:20:57 This is dangerous, as you do not check that remote
+ } else {
+ should_merge_locale_prefs_ = false;
+ }
+ } else {
+ // The global preference hasn't been set, so we need to sync and merge it.
+ should_merge_locale_prefs_ = true;
+ }
+ }
+
system::TouchpadSettings touchpad_settings;
system::MouseSettings mouse_settings;
@@ -511,7 +588,9 @@ void Preferences::ApplyPreferences(ApplyReason reason,
pref_name == prefs::kTouchHudProjectionEnabled) {
if (user_is_active) {
const bool enabled = touch_hud_projection_enabled_.GetValue();
- ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
+ // There may not be a shell, e.g., in some unit tests.
+ if (ash::Shell::HasInstance())
+ ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
}
}
@@ -531,25 +610,28 @@ void Preferences::ApplyPreferences(ApplyReason reason,
UpdateAutoRepeatRate();
}
+ if (reason == REASON_PREF_CHANGED &&
+ pref_name == prefs::kLanguagePreferredLanguagesLocal)
+ SetSyncedLocalePrefs();
+
if (reason != REASON_PREF_CHANGED && user_is_active) {
SetInputMethodList();
- } else if (pref_name == prefs::kLanguagePreloadEngines && user_is_active) {
- SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
- language_prefs::kPreloadEnginesConfigName,
- preload_engines_.GetValue());
+ } else if (pref_name == prefs::kLanguagePreloadEnginesLocal) {
+ if (user_is_active) {
+ SetLanguageConfigStringListAsCSV(
+ language_prefs::kGeneralSectionName,
+ language_prefs::kPreloadEnginesConfigName,
+ preload_engines_local_.GetValue());
+ }
+ SetSyncedLocalePrefs();
}
if (reason != REASON_PREF_CHANGED ||
- pref_name == prefs::kLanguageEnabledExtensionImes) {
- if (user_is_active) {
- std::string value(enabled_extension_imes_.GetValue());
-
- std::vector<std::string> split_values;
- if (!value.empty())
- base::SplitString(value, ',', &split_values);
-
- input_method_manager_->SetEnabledExtensionImes(&split_values);
- }
+ pref_name == prefs::kLanguageEnabledExtensionImesLocal) {
+ if (user_is_active)
+ SetEnabledExtensionImes();
+ if (reason == REASON_PREF_CHANGED)
+ SetSyncedLocalePrefs();
}
if (user_is_active) {
@@ -562,6 +644,25 @@ void Preferences::ApplyPreferences(ApplyReason reason,
void Preferences::OnIsSyncingChanged() {
DVLOG(1) << "OnIsSyncingChanged";
ForceNaturalScrollDefault();
+
+ if (should_merge_locale_prefs_ && prefs_->IsSyncing()) {
+ should_merge_locale_prefs_ = false;
+ MergeStringPrefs(preferred_languages_local_,
+ preferred_languages_,
+ prefs::kLanguagePreferredLanguagesLocal);
+ MergeStringPrefs(preload_engines_local_,
+ preload_engines_,
+ prefs::kLanguagePreloadEnginesLocal);
+ MergeStringPrefs(enabled_extension_imes_local_,
+ enabled_extension_imes_,
+ prefs::kLanguageEnabledExtensionImesLocal);
+
+ SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
+ language_prefs::kPreloadEnginesConfigName,
+ preload_engines_local_.GetValue());
+ SetEnabledExtensionImes();
+ SetSyncedLocalePrefs();
+ }
}
void Preferences::ForceNaturalScrollDefault() {
@@ -587,7 +688,7 @@ void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
// Transfers the xkb id to extension-xkb id.
if (input_method_manager_->MigrateInputMethods(&split_values))
- preload_engines_.SetValue(JoinString(split_values, ','));
+ preload_engines_local_.SetValue(JoinString(split_values, ','));
if (section == std::string(language_prefs::kGeneralSectionName) &&
name == std::string(language_prefs::kPreloadEnginesConfigName)) {
@@ -597,30 +698,49 @@ void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
}
void Preferences::SetInputMethodList() {
- // When |preload_engines_| are set, InputMethodManager::ChangeInputMethod()
- // might be called to change the current input method to the first one in the
- // |preload_engines_| list. This also updates previous/current input method
- // prefs. That's why GetValue() calls are placed before the
- // SetLanguageConfigStringListAsCSV() call below.
+ // When |preload_engines_local_| are set,
+ // InputMethodManager::ChangeInputMethod() might be called to change the
+ // current input method to the first one in the |preload_engines_local_| list.
+ // This also updates previous/current input method prefs. That's why
+ // GetValue() calls are placed before the SetLanguageConfigStringListAsCSV()
+ // call below.
const std::string previous_input_method_id =
previous_input_method_.GetValue();
const std::string current_input_method_id = current_input_method_.GetValue();
SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
language_prefs::kPreloadEnginesConfigName,
- preload_engines_.GetValue());
-
- // ChangeInputMethod() has to be called AFTER the value of |preload_engines_|
- // is sent to the InputMethodManager. Otherwise, the ChangeInputMethod request
- // might be ignored as an invalid input method ID. The ChangeInputMethod()
- // calls are also necessary to restore the previous/current input method prefs
- // which could have been modified by the SetLanguageConfigStringListAsCSV call
- // above to the original state.
+ preload_engines_local_.GetValue());
+
+ // ChangeInputMethod() has to be called AFTER the value of
+ // |preload_engines_local_| is sent to the InputMethodManager. Otherwise, the
+ // ChangeInputMethod request might be ignored as an invalid input method ID.
+ // The ChangeInputMethod() calls are also necessary to restore the
+ // previous/current input method prefs which could have been modified by the
+ // SetLanguageConfigStringListAsCSV call above to the original state.
if (!previous_input_method_id.empty())
input_method_manager_->ChangeInputMethod(previous_input_method_id);
if (!current_input_method_id.empty())
input_method_manager_->ChangeInputMethod(current_input_method_id);
}
+void Preferences::SetEnabledExtensionImes() {
+ std::string value(enabled_extension_imes_local_.GetValue());
+ std::vector<std::string> split_values;
+ if (!value.empty())
+ base::SplitString(value, ',', &split_values);
+ input_method_manager_->SetEnabledExtensionImes(&split_values);
+}
+
+void Preferences::SetSyncedLocalePrefs() {
+ // Set the language and input prefs at the same time. Otherwise, we may,
+ // e.g., use a stale languages setting but push a new preload engines setting.
+ if (!should_merge_locale_prefs_) {
+ preferred_languages_.SetValue(preferred_languages_local_.GetValue());
+ preload_engines_.SetValue(preload_engines_local_.GetValue());
+ enabled_extension_imes_.SetValue(enabled_extension_imes_local_.GetValue());
+ }
+}
+
void Preferences::UpdateAutoRepeatRate() {
input_method::AutoRepeatRate rate;
rate.initial_delay_in_ms = xkb_auto_repeat_delay_pref_.GetValue();

Powered by Google App Engine
This is Rietveld 408576698