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"
19 namespace input_method
{
22 void PersistSystemInputMethod(const std::string
& input_method
) {
23 if (!g_browser_process
|| !g_browser_process
->local_state())
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
,
43 update_succeed
= true;
46 if (!update_succeed
) {
47 // Somehow key kUsersLRUInputMethod has value of invalid type.
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
,
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
,
71 // Skip if it's not a keyboard layout. Drop input methods including
73 if (!manager
->IsLoginKeyboard(input_method
))
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
,
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).
93 user_prefs
= profile
->GetPrefs();
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
)
103 user_prefs
->SetString(prefs::kLanguagePreviousInputMethod
,
104 current_input_method_on_pref
);
105 user_prefs
->SetString(prefs::kLanguageCurrentInputMethod
,
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
,
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
;
136 PersistSystemInputMethod(current_input_method
);
138 case InputMethodManager::STATE_BROWSER_SCREEN
:
139 PersistUserInputMethod(current_input_method
, manager
, profile
);
141 case InputMethodManager::STATE_LOCK_SCREEN
:
142 // We use a special set of input methods on the screen. Do not update.
144 case InputMethodManager::STATE_TERMINATING
:
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