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