ExtensionSyncService: listen for relevant changes instead of being explicitly called...
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / input_method_persistence.cc
blob7bc298f74ff01a9137d252359d895d7df438bb8b
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.
5 #include "chrome/browser/chromeos/input_method/input_method_persistence.h"
7 #include "base/logging.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/sys_info.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chromeos/input_method/input_method_util.h"
13 #include "chrome/browser/chromeos/language_preferences.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/common/pref_names.h"
18 namespace chromeos {
19 namespace input_method {
20 namespace {
22 void PersistSystemInputMethod(const std::string& input_method) {
23 if (!g_browser_process || !g_browser_process->local_state())
24 return;
26 g_browser_process->local_state()->SetString(
27 language_prefs::kPreferredKeyboardLayout, input_method);
30 static void SetUserLRUInputMethodPreference(const std::string& username,
31 const std::string& input_method,
32 PrefService* local_state) {
33 if (!username.empty() && !local_state->ReadOnly()) {
34 bool update_succeed = false;
36 // Updater may have side-effects, therefore we do not replace
37 // entry while updater exists.
38 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
39 base::DictionaryValue* const users_lru_input_methods = updater.Get();
40 if (users_lru_input_methods) {
41 users_lru_input_methods->SetStringWithoutPathExpansion(username,
42 input_method);
43 update_succeed = true;
46 if (!update_succeed) {
47 // Somehow key kUsersLRUInputMethod has value of invalid type.
48 // Replace and retry.
49 local_state->Set(prefs::kUsersLRUInputMethod, base::DictionaryValue());
51 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
52 base::DictionaryValue* const users_lru_input_methods = updater.Get();
53 if (users_lru_input_methods) {
54 users_lru_input_methods->SetStringWithoutPathExpansion(username,
55 input_method);
56 update_succeed = true;
59 if (!update_succeed) {
60 DVLOG(1) << "Failed to replace local_state.kUsersLRUInputMethod: '"
61 << prefs::kUsersLRUInputMethod << "' for '" << username << "'";
66 // Update user LRU keyboard layout for login screen
67 static void SetUserLRUInputMethod(
68 const std::string& input_method,
69 const chromeos::input_method::InputMethodManager* const manager,
70 Profile* profile) {
71 // Skip if it's not a keyboard layout. Drop input methods including
72 // extension ones.
73 if (!manager->IsLoginKeyboard(input_method))
74 return;
76 if (profile == NULL)
77 return;
79 PrefService* const local_state = g_browser_process->local_state();
81 SetUserLRUInputMethodPreference(
82 profile->GetProfileUserName(), input_method, local_state);
85 void PersistUserInputMethod(const std::string& input_method,
86 InputMethodManager* const manager,
87 Profile* profile) {
88 PrefService* user_prefs = NULL;
89 // Persist the method on a per user basis. Note that the keyboard settings are
90 // stored per user desktop and a visiting window will use the same input
91 // method as the desktop it is on (and not of the owner of the window).
92 if (profile)
93 user_prefs = profile->GetPrefs();
94 if (!user_prefs)
95 return;
96 SetUserLRUInputMethod(input_method, manager, profile);
98 const std::string current_input_method_on_pref =
99 user_prefs->GetString(prefs::kLanguageCurrentInputMethod);
100 if (current_input_method_on_pref == input_method)
101 return;
103 user_prefs->SetString(prefs::kLanguagePreviousInputMethod,
104 current_input_method_on_pref);
105 user_prefs->SetString(prefs::kLanguageCurrentInputMethod,
106 input_method);
109 } // namespace
111 InputMethodPersistence::InputMethodPersistence(
112 InputMethodManager* input_method_manager)
113 : input_method_manager_(input_method_manager),
114 ui_session_(InputMethodManager::STATE_LOGIN_SCREEN) {
115 input_method_manager_->AddObserver(this);
118 InputMethodPersistence::~InputMethodPersistence() {
119 input_method_manager_->RemoveObserver(this);
122 void InputMethodPersistence::InputMethodChanged(InputMethodManager* manager,
123 Profile* profile,
124 bool show_message) {
125 DCHECK_EQ(input_method_manager_, manager);
126 const std::string current_input_method =
127 manager->GetActiveIMEState()->GetCurrentInputMethod().id();
128 // Save the new input method id depending on the current browser state.
129 switch (ui_session_) {
130 case InputMethodManager::STATE_LOGIN_SCREEN:
131 if (!manager->IsLoginKeyboard(current_input_method)) {
132 DVLOG(1) << "Only keyboard layouts are supported: "
133 << current_input_method;
134 return;
136 PersistSystemInputMethod(current_input_method);
137 return;
138 case InputMethodManager::STATE_BROWSER_SCREEN:
139 PersistUserInputMethod(current_input_method, manager, profile);
140 return;
141 case InputMethodManager::STATE_LOCK_SCREEN:
142 // We use a special set of input methods on the screen. Do not update.
143 return;
144 case InputMethodManager::STATE_TERMINATING:
145 return;
147 NOTREACHED();
150 void InputMethodPersistence::OnSessionStateChange(
151 InputMethodManager::UISessionState new_ui_session) {
152 ui_session_ = new_ui_session;
155 void SetUserLRUInputMethodPreferenceForTesting(const std::string& username,
156 const std::string& input_method,
157 PrefService* const local_state) {
158 SetUserLRUInputMethodPreference(username, input_method, local_state);
161 } // namespace input_method
162 } // namespace chromeos