• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "base/i18n/time_formatting.h"
8 #include "base/metrics/histogram.h"
9 #include "base/string_split.h"
10 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/chromeos/cros/cros_library.h"
13 #include "chrome/browser/chromeos/cros/input_method_library.h"
14 #include "chrome/browser/chromeos/cros/power_library.h"
15 #include "chrome/browser/chromeos/cros/touchpad_library.h"
16 #include "chrome/browser/chromeos/input_method/input_method_util.h"
17 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
18 #include "chrome/browser/chromeos/login/login_utils.h"
19 #include "chrome/browser/prefs/pref_member.h"
20 #include "chrome/browser/prefs/pref_service.h"
21 #include "chrome/common/pref_names.h"
22 #include "content/common/notification_details.h"
23 #include "content/common/notification_source.h"
24 #include "content/common/notification_type.h"
25 #include "unicode/timezone.h"
26 
27 namespace chromeos {
28 
29 static const char kFallbackInputMethodLocale[] = "en-US";
30 
Preferences()31 Preferences::Preferences() {}
32 
~Preferences()33 Preferences::~Preferences() {}
34 
35 // static
RegisterUserPrefs(PrefService * prefs)36 void Preferences::RegisterUserPrefs(PrefService* prefs) {
37   prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
38   prefs->RegisterBooleanPref(prefs::kLabsMediaplayerEnabled, false);
39   prefs->RegisterBooleanPref(prefs::kLabsAdvancedFilesystemEnabled, false);
40   // Check if the accessibility pref is already registered, which can happen
41   // in WizardController::RegisterPrefs. We still want to try to register
42   // the pref here in case of Chrome/Linux with ChromeOS=1.
43   if (prefs->FindPreference(prefs::kAccessibilityEnabled) == NULL) {
44     prefs->RegisterBooleanPref(prefs::kAccessibilityEnabled, false);
45   }
46   prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 3);
47   // Set the default based on the hour clock type of the current locale.
48   prefs->RegisterBooleanPref(prefs::kUse24HourClock,
49                              base::GetHourClockType() == base::k24HourClock);
50   prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod, "");
51   prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod, "");
52   prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngineInMenu,
53                             language_prefs::kHotkeyNextEngineInMenu);
54   prefs->RegisterStringPref(prefs::kLanguageHotkeyPreviousEngine,
55                             language_prefs::kHotkeyPreviousEngine);
56   prefs->RegisterStringPref(prefs::kLanguagePreferredLanguages,
57                             kFallbackInputMethodLocale);
58   prefs->RegisterStringPref(
59       prefs::kLanguagePreloadEngines,
60       input_method::GetHardwareInputMethodId());
61   for (size_t i = 0; i < language_prefs::kNumChewingBooleanPrefs; ++i) {
62     prefs->RegisterBooleanPref(
63         language_prefs::kChewingBooleanPrefs[i].pref_name,
64         language_prefs::kChewingBooleanPrefs[i].default_pref_value);
65   }
66   for (size_t i = 0; i < language_prefs::kNumChewingMultipleChoicePrefs; ++i) {
67     prefs->RegisterStringPref(
68         language_prefs::kChewingMultipleChoicePrefs[i].pref_name,
69         language_prefs::kChewingMultipleChoicePrefs[i].default_pref_value);
70   }
71   prefs->RegisterIntegerPref(
72       language_prefs::kChewingHsuSelKeyType.pref_name,
73       language_prefs::kChewingHsuSelKeyType.default_pref_value);
74 
75   for (size_t i = 0; i < language_prefs::kNumChewingIntegerPrefs; ++i) {
76     prefs->RegisterIntegerPref(
77         language_prefs::kChewingIntegerPrefs[i].pref_name,
78         language_prefs::kChewingIntegerPrefs[i].default_pref_value);
79   }
80   prefs->RegisterStringPref(
81       prefs::kLanguageHangulKeyboard,
82       language_prefs::kHangulKeyboardNameIDPairs[0].keyboard_id);
83   prefs->RegisterStringPref(prefs::kLanguageHangulHanjaKeys,
84                             language_prefs::kHangulHanjaKeys);
85   for (size_t i = 0; i < language_prefs::kNumPinyinBooleanPrefs; ++i) {
86     prefs->RegisterBooleanPref(
87         language_prefs::kPinyinBooleanPrefs[i].pref_name,
88         language_prefs::kPinyinBooleanPrefs[i].default_pref_value);
89   }
90   for (size_t i = 0; i < language_prefs::kNumPinyinIntegerPrefs; ++i) {
91     prefs->RegisterIntegerPref(
92         language_prefs::kPinyinIntegerPrefs[i].pref_name,
93         language_prefs::kPinyinIntegerPrefs[i].default_pref_value);
94   }
95   prefs->RegisterIntegerPref(
96       language_prefs::kPinyinDoublePinyinSchema.pref_name,
97       language_prefs::kPinyinDoublePinyinSchema.default_pref_value);
98 
99   for (size_t i = 0; i < language_prefs::kNumMozcBooleanPrefs; ++i) {
100     prefs->RegisterBooleanPref(
101         language_prefs::kMozcBooleanPrefs[i].pref_name,
102         language_prefs::kMozcBooleanPrefs[i].default_pref_value);
103   }
104   for (size_t i = 0; i < language_prefs::kNumMozcMultipleChoicePrefs; ++i) {
105     prefs->RegisterStringPref(
106         language_prefs::kMozcMultipleChoicePrefs[i].pref_name,
107         language_prefs::kMozcMultipleChoicePrefs[i].default_pref_value);
108   }
109   for (size_t i = 0; i < language_prefs::kNumMozcIntegerPrefs; ++i) {
110     prefs->RegisterIntegerPref(
111         language_prefs::kMozcIntegerPrefs[i].pref_name,
112         language_prefs::kMozcIntegerPrefs[i].default_pref_value);
113   }
114   prefs->RegisterIntegerPref(prefs::kLanguageXkbRemapSearchKeyTo,
115                              input_method::kSearchKey);
116   prefs->RegisterIntegerPref(prefs::kLanguageXkbRemapControlKeyTo,
117                              input_method::kLeftControlKey);
118   prefs->RegisterIntegerPref(prefs::kLanguageXkbRemapAltKeyTo,
119                              input_method::kLeftAltKey);
120   prefs->RegisterBooleanPref(prefs::kLanguageXkbAutoRepeatEnabled, true);
121   prefs->RegisterIntegerPref(prefs::kLanguageXkbAutoRepeatDelay,
122                              language_prefs::kXkbAutoRepeatDelayInMs);
123   prefs->RegisterIntegerPref(prefs::kLanguageXkbAutoRepeatInterval,
124                              language_prefs::kXkbAutoRepeatIntervalInMs);
125 
126   // Screen lock default to off.
127   prefs->RegisterBooleanPref(prefs::kEnableScreenLock, false);
128 
129   // Mobile plan notifications default to on.
130   prefs->RegisterBooleanPref(prefs::kShowPlanNotifications, true);
131 
132   // 3G first-time usage promo will be shown at least once.
133   prefs->RegisterBooleanPref(prefs::kShow3gPromoNotification, true);
134 
135   // Carrier deal notification shown count defaults to 0.
136   prefs->RegisterIntegerPref(prefs::kCarrierDealPromoShown, 0);
137 
138   // The map of timestamps of the last used file browser handlers.
139   prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers);
140 }
141 
Init(PrefService * prefs)142 void Preferences::Init(PrefService* prefs) {
143   tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
144   accessibility_enabled_.Init(prefs::kAccessibilityEnabled, prefs, this);
145   sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, this);
146   use_24hour_clock_.Init(prefs::kUse24HourClock, prefs, this);
147   language_hotkey_next_engine_in_menu_.Init(
148       prefs::kLanguageHotkeyNextEngineInMenu, prefs, this);
149   language_hotkey_previous_engine_.Init(
150       prefs::kLanguageHotkeyPreviousEngine, prefs, this);
151   language_preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
152                                      prefs, this);
153   language_preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, this);
154   for (size_t i = 0; i < language_prefs::kNumChewingBooleanPrefs; ++i) {
155     language_chewing_boolean_prefs_[i].Init(
156         language_prefs::kChewingBooleanPrefs[i].pref_name, prefs, this);
157   }
158   for (size_t i = 0; i < language_prefs::kNumChewingMultipleChoicePrefs; ++i) {
159     language_chewing_multiple_choice_prefs_[i].Init(
160         language_prefs::kChewingMultipleChoicePrefs[i].pref_name, prefs, this);
161   }
162   language_chewing_hsu_sel_key_type_.Init(
163       language_prefs::kChewingHsuSelKeyType.pref_name, prefs, this);
164   for (size_t i = 0; i < language_prefs::kNumChewingIntegerPrefs; ++i) {
165     language_chewing_integer_prefs_[i].Init(
166         language_prefs::kChewingIntegerPrefs[i].pref_name, prefs, this);
167   }
168   language_hangul_keyboard_.Init(prefs::kLanguageHangulKeyboard, prefs, this);
169   language_hangul_hanja_keys_.Init(
170       prefs::kLanguageHangulHanjaKeys, prefs, this);
171   for (size_t i = 0; i < language_prefs::kNumPinyinBooleanPrefs; ++i) {
172     language_pinyin_boolean_prefs_[i].Init(
173         language_prefs::kPinyinBooleanPrefs[i].pref_name, prefs, this);
174   }
175   for (size_t i = 0; i < language_prefs::kNumPinyinIntegerPrefs; ++i) {
176     language_pinyin_int_prefs_[i].Init(
177         language_prefs::kPinyinIntegerPrefs[i].pref_name, prefs, this);
178   }
179   language_pinyin_double_pinyin_schema_.Init(
180       language_prefs::kPinyinDoublePinyinSchema.pref_name, prefs, this);
181   for (size_t i = 0; i < language_prefs::kNumMozcBooleanPrefs; ++i) {
182     language_mozc_boolean_prefs_[i].Init(
183         language_prefs::kMozcBooleanPrefs[i].pref_name, prefs, this);
184   }
185   for (size_t i = 0; i < language_prefs::kNumMozcMultipleChoicePrefs; ++i) {
186     language_mozc_multiple_choice_prefs_[i].Init(
187         language_prefs::kMozcMultipleChoicePrefs[i].pref_name, prefs, this);
188   }
189   for (size_t i = 0; i < language_prefs::kNumMozcIntegerPrefs; ++i) {
190     language_mozc_integer_prefs_[i].Init(
191         language_prefs::kMozcIntegerPrefs[i].pref_name, prefs, this);
192   }
193   language_xkb_remap_search_key_to_.Init(
194       prefs::kLanguageXkbRemapSearchKeyTo, prefs, this);
195   language_xkb_remap_control_key_to_.Init(
196       prefs::kLanguageXkbRemapControlKeyTo, prefs, this);
197   language_xkb_remap_alt_key_to_.Init(
198       prefs::kLanguageXkbRemapAltKeyTo, prefs, this);
199   language_xkb_auto_repeat_enabled_.Init(
200       prefs::kLanguageXkbAutoRepeatEnabled, prefs, this);
201   language_xkb_auto_repeat_delay_pref_.Init(
202       prefs::kLanguageXkbAutoRepeatDelay, prefs, this);
203   language_xkb_auto_repeat_interval_pref_.Init(
204       prefs::kLanguageXkbAutoRepeatInterval, prefs, this);
205 
206   enable_screen_lock_.Init(prefs::kEnableScreenLock, prefs, this);
207 
208   // Initialize preferences to currently saved state.
209   NotifyPrefChanged(NULL);
210 
211   // If a guest is logged in, initialize the prefs as if this is the first
212   // login.
213   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) {
214     LoginUtils::Get()->SetFirstLoginPrefs(prefs);
215   }
216 }
217 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)218 void Preferences::Observe(NotificationType type,
219                           const NotificationSource& source,
220                           const NotificationDetails& details) {
221   if (type == NotificationType::PREF_CHANGED)
222     NotifyPrefChanged(Details<std::string>(details).ptr());
223 }
224 
NotifyPrefChanged(const std::string * pref_name)225 void Preferences::NotifyPrefChanged(const std::string* pref_name) {
226   if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
227     bool enabled = tap_to_click_enabled_.GetValue();
228     CrosLibrary::Get()->GetTouchpadLibrary()->SetTapToClick(enabled);
229     if (pref_name)
230       UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Changed", enabled);
231     else
232       UMA_HISTOGRAM_BOOLEAN("Touchpad.TapToClick.Started", enabled);
233   }
234   if (!pref_name || *pref_name == prefs::kTouchpadSensitivity) {
235     int sensitivity = sensitivity_.GetValue();
236     CrosLibrary::Get()->GetTouchpadLibrary()->SetSensitivity(sensitivity);
237     if (pref_name) {
238       UMA_HISTOGRAM_CUSTOM_COUNTS(
239           "Touchpad.Sensitivity.Changed", sensitivity, 1, 5, 5);
240     } else {
241       UMA_HISTOGRAM_CUSTOM_COUNTS(
242           "Touchpad.Sensitivity.Started", sensitivity, 1, 5, 5);
243     }
244   }
245 
246   // We don't handle prefs::kLanguageCurrentInputMethod and PreviousInputMethod
247   // here.
248 
249   if (!pref_name || *pref_name == prefs::kLanguageHotkeyNextEngineInMenu) {
250     SetLanguageConfigStringListAsCSV(
251         language_prefs::kHotKeySectionName,
252         language_prefs::kNextEngineInMenuConfigName,
253         language_hotkey_next_engine_in_menu_.GetValue());
254   }
255   if (!pref_name || *pref_name == prefs::kLanguageHotkeyPreviousEngine) {
256     SetLanguageConfigStringListAsCSV(
257         language_prefs::kHotKeySectionName,
258         language_prefs::kPreviousEngineConfigName,
259         language_hotkey_previous_engine_.GetValue());
260   }
261   if (!pref_name || *pref_name == prefs::kLanguagePreferredLanguages) {
262     // Unlike kLanguagePreloadEngines and some other input method
263     // preferencs, we don't need to send this to ibus-daemon.
264   }
265 
266   // Here, we set up the the modifier key mapping. This has to be done
267   // before changing the current keyboard layout, so that the modifier key
268   // preference is properly preserved. For this reason, we should do this
269   // before setting preload engines, that could change the current
270   // keyboard layout as needed.
271   if (!pref_name || (*pref_name == prefs::kLanguageXkbRemapSearchKeyTo ||
272                      *pref_name == prefs::kLanguageXkbRemapControlKeyTo ||
273                      *pref_name == prefs::kLanguageXkbRemapAltKeyTo)) {
274     UpdateModifierKeyMapping();
275   }
276   if (!pref_name || *pref_name == prefs::kLanguageXkbAutoRepeatEnabled) {
277     const bool enabled = language_xkb_auto_repeat_enabled_.GetValue();
278     input_method::SetAutoRepeatEnabled(enabled);
279   }
280   if (!pref_name || ((*pref_name == prefs::kLanguageXkbAutoRepeatDelay) ||
281                      (*pref_name == prefs::kLanguageXkbAutoRepeatInterval))) {
282     UpdateAutoRepeatRate();
283   }
284 
285   if (!pref_name || *pref_name == prefs::kLanguagePreloadEngines) {
286     SetLanguageConfigStringListAsCSV(language_prefs::kGeneralSectionName,
287                                      language_prefs::kPreloadEnginesConfigName,
288                                      language_preload_engines_.GetValue());
289   }
290   for (size_t i = 0; i < language_prefs::kNumChewingBooleanPrefs; ++i) {
291     if (!pref_name ||
292         *pref_name == language_prefs::kChewingBooleanPrefs[i].pref_name) {
293       SetLanguageConfigBoolean(
294           language_prefs::kChewingSectionName,
295           language_prefs::kChewingBooleanPrefs[i].ibus_config_name,
296           language_chewing_boolean_prefs_[i].GetValue());
297     }
298   }
299   for (size_t i = 0; i < language_prefs::kNumChewingMultipleChoicePrefs; ++i) {
300     if (!pref_name ||
301         *pref_name ==
302         language_prefs::kChewingMultipleChoicePrefs[i].pref_name) {
303       SetLanguageConfigString(
304           language_prefs::kChewingSectionName,
305           language_prefs::kChewingMultipleChoicePrefs[i].ibus_config_name,
306           language_chewing_multiple_choice_prefs_[i].GetValue());
307     }
308   }
309   if (!pref_name ||
310       *pref_name == language_prefs::kChewingHsuSelKeyType.pref_name) {
311     SetLanguageConfigInteger(
312         language_prefs::kChewingSectionName,
313         language_prefs::kChewingHsuSelKeyType.ibus_config_name,
314         language_chewing_hsu_sel_key_type_.GetValue());
315   }
316   for (size_t i = 0; i < language_prefs::kNumChewingIntegerPrefs; ++i) {
317     if (!pref_name ||
318         *pref_name == language_prefs::kChewingIntegerPrefs[i].pref_name) {
319       SetLanguageConfigInteger(
320           language_prefs::kChewingSectionName,
321           language_prefs::kChewingIntegerPrefs[i].ibus_config_name,
322           language_chewing_integer_prefs_[i].GetValue());
323     }
324   }
325   if (!pref_name ||
326       *pref_name == prefs::kLanguageHangulKeyboard) {
327     SetLanguageConfigString(language_prefs::kHangulSectionName,
328                             language_prefs::kHangulKeyboardConfigName,
329                             language_hangul_keyboard_.GetValue());
330   }
331   if (!pref_name || *pref_name == prefs::kLanguageHangulHanjaKeys) {
332     SetLanguageConfigString(language_prefs::kHangulSectionName,
333                             language_prefs::kHangulHanjaKeysConfigName,
334                             language_hangul_hanja_keys_.GetValue());
335   }
336   for (size_t i = 0; i < language_prefs::kNumPinyinBooleanPrefs; ++i) {
337     if (!pref_name ||
338         *pref_name == language_prefs::kPinyinBooleanPrefs[i].pref_name) {
339       SetLanguageConfigBoolean(
340           language_prefs::kPinyinSectionName,
341           language_prefs::kPinyinBooleanPrefs[i].ibus_config_name,
342           language_pinyin_boolean_prefs_[i].GetValue());
343     }
344   }
345   for (size_t i = 0; i < language_prefs::kNumPinyinIntegerPrefs; ++i) {
346     if (!pref_name ||
347         *pref_name == language_prefs::kPinyinIntegerPrefs[i].pref_name) {
348       SetLanguageConfigInteger(
349           language_prefs::kPinyinSectionName,
350           language_prefs::kPinyinIntegerPrefs[i].ibus_config_name,
351           language_pinyin_int_prefs_[i].GetValue());
352     }
353   }
354   if (!pref_name ||
355       *pref_name == language_prefs::kPinyinDoublePinyinSchema.pref_name) {
356     SetLanguageConfigInteger(
357         language_prefs::kPinyinSectionName,
358         language_prefs::kPinyinDoublePinyinSchema.ibus_config_name,
359         language_pinyin_double_pinyin_schema_.GetValue());
360   }
361   for (size_t i = 0; i < language_prefs::kNumMozcBooleanPrefs; ++i) {
362     if (!pref_name ||
363         *pref_name == language_prefs::kMozcBooleanPrefs[i].pref_name) {
364       SetLanguageConfigBoolean(
365           language_prefs::kMozcSectionName,
366           language_prefs::kMozcBooleanPrefs[i].ibus_config_name,
367           language_mozc_boolean_prefs_[i].GetValue());
368     }
369   }
370   for (size_t i = 0; i < language_prefs::kNumMozcMultipleChoicePrefs; ++i) {
371     if (!pref_name ||
372         *pref_name == language_prefs::kMozcMultipleChoicePrefs[i].pref_name) {
373       SetLanguageConfigString(
374           language_prefs::kMozcSectionName,
375           language_prefs::kMozcMultipleChoicePrefs[i].ibus_config_name,
376           language_mozc_multiple_choice_prefs_[i].GetValue());
377     }
378   }
379   for (size_t i = 0; i < language_prefs::kNumMozcIntegerPrefs; ++i) {
380     if (!pref_name ||
381         *pref_name == language_prefs::kMozcIntegerPrefs[i].pref_name) {
382       SetLanguageConfigInteger(
383           language_prefs::kMozcSectionName,
384           language_prefs::kMozcIntegerPrefs[i].ibus_config_name,
385           language_mozc_integer_prefs_[i].GetValue());
386     }
387   }
388 
389   // Init or update power manager config.
390   if (!pref_name || *pref_name == prefs::kEnableScreenLock) {
391     CrosLibrary::Get()->GetPowerLibrary()->EnableScreenLock(
392         enable_screen_lock_.GetValue());
393   }
394 }
395 
SetLanguageConfigBoolean(const char * section,const char * name,bool value)396 void Preferences::SetLanguageConfigBoolean(const char* section,
397                                            const char* name,
398                                            bool value) {
399   ImeConfigValue config;
400   config.type = ImeConfigValue::kValueTypeBool;
401   config.bool_value = value;
402   CrosLibrary::Get()->GetInputMethodLibrary()->
403       SetImeConfig(section, name, config);
404 }
405 
SetLanguageConfigInteger(const char * section,const char * name,int value)406 void Preferences::SetLanguageConfigInteger(const char* section,
407                                            const char* name,
408                                            int value) {
409   ImeConfigValue config;
410   config.type = ImeConfigValue::kValueTypeInt;
411   config.int_value = value;
412   CrosLibrary::Get()->GetInputMethodLibrary()->
413       SetImeConfig(section, name, config);
414 }
415 
SetLanguageConfigString(const char * section,const char * name,const std::string & value)416 void Preferences::SetLanguageConfigString(const char* section,
417                                           const char* name,
418                                           const std::string& value) {
419   ImeConfigValue config;
420   config.type = ImeConfigValue::kValueTypeString;
421   config.string_value = value;
422   CrosLibrary::Get()->GetInputMethodLibrary()->
423       SetImeConfig(section, name, config);
424 }
425 
SetLanguageConfigStringList(const char * section,const char * name,const std::vector<std::string> & values)426 void Preferences::SetLanguageConfigStringList(
427     const char* section,
428     const char* name,
429     const std::vector<std::string>& values) {
430   ImeConfigValue config;
431   config.type = ImeConfigValue::kValueTypeStringList;
432   for (size_t i = 0; i < values.size(); ++i)
433     config.string_list_value.push_back(values[i]);
434 
435   CrosLibrary::Get()->GetInputMethodLibrary()->
436       SetImeConfig(section, name, config);
437 }
438 
SetLanguageConfigStringListAsCSV(const char * section,const char * name,const std::string & value)439 void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
440                                                    const char* name,
441                                                    const std::string& value) {
442   VLOG(1) << "Setting " << name << " to '" << value << "'";
443 
444   std::vector<std::string> split_values;
445   if (!value.empty())
446     base::SplitString(value, ',', &split_values);
447 
448   // We should call the cros API even when |value| is empty, to disable default
449   // config.
450   SetLanguageConfigStringList(section, name, split_values);
451 }
452 
UpdateModifierKeyMapping()453 void Preferences::UpdateModifierKeyMapping() {
454   const int search_remap = language_xkb_remap_search_key_to_.GetValue();
455   const int control_remap = language_xkb_remap_control_key_to_.GetValue();
456   const int alt_remap = language_xkb_remap_alt_key_to_.GetValue();
457   if ((search_remap < input_method::kNumModifierKeys) && (search_remap >= 0) &&
458       (control_remap < input_method::kNumModifierKeys) &&
459       (control_remap >= 0) &&
460       (alt_remap < input_method::kNumModifierKeys) && (alt_remap >= 0)) {
461     input_method::ModifierMap modifier_map;
462     modifier_map.push_back(
463         input_method::ModifierKeyPair(
464             input_method::kSearchKey,
465             input_method::ModifierKey(search_remap)));
466     modifier_map.push_back(
467         input_method::ModifierKeyPair(
468             input_method::kLeftControlKey,
469             input_method::ModifierKey(control_remap)));
470     modifier_map.push_back(
471         input_method::ModifierKeyPair(
472             input_method::kLeftAltKey,
473             input_method::ModifierKey(alt_remap)));
474     input_method::RemapModifierKeys(modifier_map);
475   } else {
476     LOG(ERROR) << "Failed to remap modifier keys. Unexpected value(s): "
477                << search_remap << ", " << control_remap << ", " << alt_remap;
478   }
479 }
480 
UpdateAutoRepeatRate()481 void Preferences::UpdateAutoRepeatRate() {
482   input_method::AutoRepeatRate rate;
483   rate.initial_delay_in_ms = language_xkb_auto_repeat_delay_pref_.GetValue();
484   rate.repeat_interval_in_ms =
485       language_xkb_auto_repeat_interval_pref_.GetValue();
486   DCHECK(rate.initial_delay_in_ms > 0);
487   DCHECK(rate.repeat_interval_in_ms > 0);
488   input_method::SetAutoRepeatRate(rate);
489 }
490 
491 }  // namespace chromeos
492