preferences.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2009 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/string_util.h"
8#include "base/utf_string_conversions.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chromeos/cros/cros_library.h"
11#include "chrome/browser/chromeos/cros/input_method_library.h"
12#include "chrome/browser/chromeos/cros/synaptics_library.h"
13#include "chrome/browser/chromeos/input_method/input_method_util.h"
14#include "chrome/browser/pref_member.h"
15#include "chrome/browser/pref_service.h"
16#include "chrome/common/notification_service.h"
17#include "chrome/common/pref_names.h"
18#include "unicode/timezone.h"
19
20namespace chromeos {
21
22static const char kFallbackInputMethodLocale[] = "en-US";
23
24// static
25void Preferences::RegisterUserPrefs(PrefService* prefs) {
26  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
27  prefs->RegisterBooleanPref(prefs::kLabsMediaplayerEnabled, false);
28  prefs->RegisterBooleanPref(prefs::kLabsAdvancedFilesystemEnabled, false);
29  prefs->RegisterBooleanPref(prefs::kAccessibilityEnabled, false);
30  prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, false);
31  prefs->RegisterIntegerPref(prefs::kTouchpadSpeedFactor, 9);
32  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 5);
33  prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod, "");
34  prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod, "");
35  prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngineInMenu,
36                            kHotkeyNextEngineInMenu);
37  prefs->RegisterStringPref(prefs::kLanguageHotkeyPreviousEngine,
38                            kHotkeyPreviousEngine);
39  prefs->RegisterStringPref(prefs::kLanguagePreferredLanguages, "");
40  prefs->RegisterStringPref(prefs::kLanguagePreloadEngines,
41                            kFallbackInputMethodId);  // EN layout
42  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
43    prefs->RegisterBooleanPref(kChewingBooleanPrefs[i].pref_name,
44                               kChewingBooleanPrefs[i].default_pref_value);
45  }
46  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
47    prefs->RegisterStringPref(
48        kChewingMultipleChoicePrefs[i].pref_name,
49        kChewingMultipleChoicePrefs[i].default_pref_value);
50  }
51  prefs->RegisterIntegerPref(kChewingHsuSelKeyType.pref_name,
52                             kChewingHsuSelKeyType.default_pref_value);
53
54  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
55    prefs->RegisterIntegerPref(kChewingIntegerPrefs[i].pref_name,
56                               kChewingIntegerPrefs[i].default_pref_value);
57  }
58  prefs->RegisterStringPref(
59      prefs::kLanguageHangulKeyboard,
60      kHangulKeyboardNameIDPairs[0].keyboard_id);
61  prefs->RegisterStringPref(prefs::kLanguageHangulHanjaKeys, kHangulHanjaKeys);
62  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
63    prefs->RegisterBooleanPref(kPinyinBooleanPrefs[i].pref_name,
64                               kPinyinBooleanPrefs[i].default_pref_value);
65  }
66  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
67    prefs->RegisterIntegerPref(kPinyinIntegerPrefs[i].pref_name,
68                               kPinyinIntegerPrefs[i].default_pref_value);
69  }
70  prefs->RegisterIntegerPref(kPinyinDoublePinyinSchema.pref_name,
71                             kPinyinDoublePinyinSchema.default_pref_value);
72
73  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
74    prefs->RegisterBooleanPref(kMozcBooleanPrefs[i].pref_name,
75                               kMozcBooleanPrefs[i].default_pref_value);
76  }
77  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
78    prefs->RegisterStringPref(
79        kMozcMultipleChoicePrefs[i].pref_name,
80        kMozcMultipleChoicePrefs[i].default_pref_value);
81  }
82  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
83    prefs->RegisterIntegerPref(kMozcIntegerPrefs[i].pref_name,
84                               kMozcIntegerPrefs[i].default_pref_value);
85  }
86}
87
88void Preferences::Init(PrefService* prefs) {
89  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
90  accessibility_enabled_.Init(prefs::kAccessibilityEnabled, prefs, this);
91  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
92  speed_factor_.Init(prefs::kTouchpadSpeedFactor, prefs, this);
93  sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, this);
94  language_hotkey_next_engine_in_menu_.Init(
95      prefs::kLanguageHotkeyNextEngineInMenu, prefs, this);
96  language_hotkey_previous_engine_.Init(
97      prefs::kLanguageHotkeyPreviousEngine, prefs, this);
98  language_preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
99                                     prefs, this);
100  language_preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, this);
101  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
102    language_chewing_boolean_prefs_[i].Init(
103        kChewingBooleanPrefs[i].pref_name, prefs, this);
104  }
105  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
106    language_chewing_multiple_choice_prefs_[i].Init(
107        kChewingMultipleChoicePrefs[i].pref_name, prefs, this);
108  }
109  language_chewing_hsu_sel_key_type_.Init(
110      kChewingHsuSelKeyType.pref_name, prefs, this);
111  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
112    language_chewing_integer_prefs_[i].Init(
113        kChewingIntegerPrefs[i].pref_name, prefs, this);
114  }
115  language_hangul_keyboard_.Init(prefs::kLanguageHangulKeyboard, prefs, this);
116  language_hangul_hanja_keys_.Init(
117      prefs::kLanguageHangulHanjaKeys, prefs, this);
118  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
119    language_pinyin_boolean_prefs_[i].Init(
120        kPinyinBooleanPrefs[i].pref_name, prefs, this);
121  }
122  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
123    language_pinyin_int_prefs_[i].Init(
124        kPinyinIntegerPrefs[i].pref_name, prefs, this);
125  }
126  language_pinyin_double_pinyin_schema_.Init(
127      kPinyinDoublePinyinSchema.pref_name, prefs, this);
128  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
129    language_mozc_boolean_prefs_[i].Init(
130        kMozcBooleanPrefs[i].pref_name, prefs, this);
131  }
132  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
133    language_mozc_multiple_choice_prefs_[i].Init(
134        kMozcMultipleChoicePrefs[i].pref_name, prefs, this);
135  }
136  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
137    language_mozc_integer_prefs_[i].Init(
138        kMozcIntegerPrefs[i].pref_name, prefs, this);
139  }
140
141  std::string locale(g_browser_process->GetApplicationLocale());
142  // Add input methods based on the application locale when the user first
143  // logs in. For instance, if the user chooses Japanese as the UI
144  // language at the first login, we'll add input methods associated with
145  // Japanese, such as mozc.
146  if (locale != kFallbackInputMethodLocale &&
147      !prefs->HasPrefPath(prefs::kLanguagePreloadEngines)) {
148    std::string preload_engines(language_preload_engines_.GetValue());
149    std::vector<std::string> input_method_ids;
150    input_method::GetInputMethodIdsFromLanguageCode(
151        locale, input_method::kAllInputMethods, &input_method_ids);
152    if (!input_method_ids.empty()) {
153      if (!preload_engines.empty())
154        preload_engines += ',';
155      preload_engines += JoinString(input_method_ids, ',');
156    }
157    language_preload_engines_.SetValue(preload_engines);
158  }
159  // Add the UI language to the preferred languages the user first logs in.
160  if (!prefs->HasPrefPath(prefs::kLanguagePreferredLanguages)) {
161    language_preferred_languages_.SetValue(locale);
162  }
163
164  // Initialize touchpad settings to what's saved in user preferences.
165  NotifyPrefChanged(NULL);
166}
167
168void Preferences::Observe(NotificationType type,
169                          const NotificationSource& source,
170                          const NotificationDetails& details) {
171  if (type == NotificationType::PREF_CHANGED)
172    NotifyPrefChanged(Details<std::wstring>(details).ptr());
173}
174
175void Preferences::NotifyPrefChanged(const std::wstring* pref_name) {
176  if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
177    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
178        PARAM_BOOL_TAP_TO_CLICK,
179        tap_to_click_enabled_.GetValue());
180  }
181  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled) {
182    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
183        PARAM_BOOL_VERTICAL_EDGE_SCROLLING,
184        vert_edge_scroll_enabled_.GetValue());
185  }
186  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor) {
187    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
188        PARAM_RANGE_SPEED_SENSITIVITY,
189        speed_factor_.GetValue());
190  }
191  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity) {
192    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
193          PARAM_RANGE_TOUCH_SENSITIVITY,
194          sensitivity_.GetValue());
195  }
196
197  // We don't handle prefs::kLanguageCurrentInputMethod and PreviousInputMethod
198  // here.
199
200  if (!pref_name || *pref_name == prefs::kLanguageHotkeyNextEngineInMenu) {
201    SetLanguageConfigStringListAsCSV(
202        kHotKeySectionName,
203        kNextEngineInMenuConfigName,
204        language_hotkey_next_engine_in_menu_.GetValue());
205  }
206  if (!pref_name || *pref_name == prefs::kLanguageHotkeyPreviousEngine) {
207    SetLanguageConfigStringListAsCSV(
208        kHotKeySectionName,
209        kPreviousEngineConfigName,
210        language_hotkey_previous_engine_.GetValue());
211  }
212  if (!pref_name || *pref_name == prefs::kLanguagePreferredLanguages) {
213    // Unlike kLanguagePreloadEngines and some other input method
214    // preferencs, we don't need to send this to ibus-daemon.
215  }
216  if (!pref_name || *pref_name == prefs::kLanguagePreloadEngines) {
217    SetLanguageConfigStringListAsCSV(kGeneralSectionName,
218                                     kPreloadEnginesConfigName,
219                                     language_preload_engines_.GetValue());
220  }
221  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
222    if (!pref_name || *pref_name == kChewingBooleanPrefs[i].pref_name) {
223      SetLanguageConfigBoolean(kChewingSectionName,
224                               kChewingBooleanPrefs[i].ibus_config_name,
225                               language_chewing_boolean_prefs_[i].GetValue());
226    }
227  }
228  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
229    if (!pref_name || *pref_name == kChewingMultipleChoicePrefs[i].pref_name) {
230      SetLanguageConfigString(
231          kChewingSectionName,
232          kChewingMultipleChoicePrefs[i].ibus_config_name,
233          language_chewing_multiple_choice_prefs_[i].GetValue());
234    }
235  }
236  if (!pref_name || *pref_name == kChewingHsuSelKeyType.pref_name) {
237    SetLanguageConfigInteger(
238        kChewingSectionName,
239        kChewingHsuSelKeyType.ibus_config_name,
240        language_chewing_hsu_sel_key_type_.GetValue());
241  }
242  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
243    if (!pref_name || *pref_name == kChewingIntegerPrefs[i].pref_name) {
244      SetLanguageConfigInteger(kChewingSectionName,
245                               kChewingIntegerPrefs[i].ibus_config_name,
246                               language_chewing_integer_prefs_[i].GetValue());
247    }
248  }
249  if (!pref_name || *pref_name == prefs::kLanguageHangulKeyboard) {
250    SetLanguageConfigString(kHangulSectionName, kHangulKeyboardConfigName,
251                            language_hangul_keyboard_.GetValue());
252  }
253  if (!pref_name || *pref_name == prefs::kLanguageHangulHanjaKeys) {
254    SetLanguageConfigString(kHangulSectionName, kHangulHanjaKeysConfigName,
255                            language_hangul_hanja_keys_.GetValue());
256  }
257  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
258    if (!pref_name || *pref_name == kPinyinBooleanPrefs[i].pref_name) {
259      SetLanguageConfigBoolean(kPinyinSectionName,
260                               kPinyinBooleanPrefs[i].ibus_config_name,
261                               language_pinyin_boolean_prefs_[i].GetValue());
262    }
263  }
264  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
265    if (!pref_name || *pref_name == kPinyinIntegerPrefs[i].pref_name) {
266      SetLanguageConfigInteger(kPinyinSectionName,
267                               kPinyinIntegerPrefs[i].ibus_config_name,
268                               language_pinyin_int_prefs_[i].GetValue());
269    }
270  }
271  if (!pref_name || *pref_name == kPinyinDoublePinyinSchema.pref_name) {
272    SetLanguageConfigInteger(
273        kPinyinSectionName,
274        kPinyinDoublePinyinSchema.ibus_config_name,
275        language_pinyin_double_pinyin_schema_.GetValue());
276  }
277  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
278    if (!pref_name || *pref_name == kMozcBooleanPrefs[i].pref_name) {
279      SetLanguageConfigBoolean(kMozcSectionName,
280                               kMozcBooleanPrefs[i].ibus_config_name,
281                               language_mozc_boolean_prefs_[i].GetValue());
282    }
283  }
284  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
285    if (!pref_name || *pref_name == kMozcMultipleChoicePrefs[i].pref_name) {
286      SetLanguageConfigString(
287          kMozcSectionName,
288          kMozcMultipleChoicePrefs[i].ibus_config_name,
289          language_mozc_multiple_choice_prefs_[i].GetValue());
290    }
291  }
292  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
293    if (!pref_name || *pref_name == kMozcIntegerPrefs[i].pref_name) {
294      SetLanguageConfigInteger(kMozcSectionName,
295                               kMozcIntegerPrefs[i].ibus_config_name,
296                               language_mozc_integer_prefs_[i].GetValue());
297    }
298  }
299}
300
301void Preferences::SetLanguageConfigBoolean(const char* section,
302                                           const char* name,
303                                           bool value) {
304  ImeConfigValue config;
305  config.type = ImeConfigValue::kValueTypeBool;
306  config.bool_value = value;
307  CrosLibrary::Get()->GetInputMethodLibrary()->
308      SetImeConfig(section, name, config);
309}
310
311void Preferences::SetLanguageConfigInteger(const char* section,
312                                           const char* name,
313                                           int value) {
314  ImeConfigValue config;
315  config.type = ImeConfigValue::kValueTypeInt;
316  config.int_value = value;
317  CrosLibrary::Get()->GetInputMethodLibrary()->
318      SetImeConfig(section, name, config);
319}
320
321void Preferences::SetLanguageConfigString(const char* section,
322                                          const char* name,
323                                          const std::string& value) {
324  ImeConfigValue config;
325  config.type = ImeConfigValue::kValueTypeString;
326  config.string_value = value;
327  CrosLibrary::Get()->GetInputMethodLibrary()->
328      SetImeConfig(section, name, config);
329}
330
331void Preferences::SetLanguageConfigStringList(
332    const char* section,
333    const char* name,
334    const std::vector<std::string>& values) {
335  ImeConfigValue config;
336  config.type = ImeConfigValue::kValueTypeStringList;
337  for (size_t i = 0; i < values.size(); ++i)
338    config.string_list_value.push_back(values[i]);
339
340  CrosLibrary::Get()->GetInputMethodLibrary()->
341      SetImeConfig(section, name, config);
342}
343
344void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
345                                                   const char* name,
346                                                   const std::string& value) {
347  LOG(INFO) << "Setting " << name << " to '" << value << "'";
348
349  std::vector<std::string> split_values;
350  if (!value.empty())
351    SplitString(value, ',', &split_values);
352
353  // We should call the cros API even when |value| is empty, to disable default
354  // config.
355  SetLanguageConfigStringList(section, name, split_values);
356}
357
358}  // namespace chromeos
359