Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / input_method / input_method_persistence.cc
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.
4
5 #include "chrome/browser/chromeos/input_method/input_method_persistence.h"
6
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/chromeos/login/users/user_manager.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/common/pref_names.h"
18
19 namespace chromeos {
20 namespace input_method {
21 namespace {
22
23 void PersistSystemInputMethod(const std::string& input_method) {
24   if (!g_browser_process || !g_browser_process->local_state())
25     return;
26
27   g_browser_process->local_state()->SetString(
28         language_prefs::kPreferredKeyboardLayout, input_method);
29 }
30
31 // Update user LRU keyboard layout for login screen
32 static void SetUserLRUInputMethod(
33     const std::string& input_method,
34     const chromeos::input_method::InputMethodManager* const manager,
35     Profile* profile) {
36   // Skip if it's not a keyboard layout. Drop input methods including
37   // extension ones.
38   if (!manager->IsLoginKeyboard(input_method))
39     return;
40
41   PrefService* const local_state = g_browser_process->local_state();
42
43   if (profile == NULL)
44     return;
45
46   const std::string username = profile->GetProfileName();
47   if (base::SysInfo::IsRunningOnChromeOS() && !username.empty() &&
48       !local_state->ReadOnly()) {
49     bool update_succeed = false;
50     {
51       // Updater may have side-effects, therefore we do not replace
52       // entry while updater exists.
53       DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
54       base::DictionaryValue* const users_lru_input_methods = updater.Get();
55       if (users_lru_input_methods) {
56         users_lru_input_methods->SetStringWithoutPathExpansion(username,
57                                                                input_method);
58         update_succeed = true;
59       }
60     }
61     if (!update_succeed) {
62       // Somehow key kUsersLRUInputMethod has value of invalid type.
63       // Replace and retry.
64       local_state->Set(prefs::kUsersLRUInputMethod, base::DictionaryValue());
65
66       DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
67       base::DictionaryValue* const users_lru_input_methods = updater.Get();
68       if (users_lru_input_methods) {
69         users_lru_input_methods->SetStringWithoutPathExpansion(username,
70                                                                input_method);
71         update_succeed = true;
72       }
73     }
74     if (!update_succeed) {
75       DVLOG(1) << "Failed to replace local_state.kUsersLRUInputMethod: '"
76                << prefs::kUsersLRUInputMethod << "' for '" << username << "'";
77     }
78   }
79 }
80
81 void PersistUserInputMethod(const std::string& input_method,
82                             InputMethodManager* const manager) {
83   PrefService* user_prefs = NULL;
84   // Persist the method on a per user basis. Note that the keyboard settings are
85   // stored per user desktop and a visiting window will use the same input
86   // method as the desktop it is on (and not of the owner of the window).
87   Profile* profile = ProfileManager::GetActiveUserProfile();
88   if (profile)
89     user_prefs = profile->GetPrefs();
90   if (!user_prefs)
91     return;
92   SetUserLRUInputMethod(input_method, manager, profile);
93
94   const std::string current_input_method_on_pref =
95       user_prefs->GetString(prefs::kLanguageCurrentInputMethod);
96   if (current_input_method_on_pref == input_method)
97     return;
98
99   user_prefs->SetString(prefs::kLanguagePreviousInputMethod,
100                         current_input_method_on_pref);
101   user_prefs->SetString(prefs::kLanguageCurrentInputMethod,
102                         input_method);
103 }
104
105 }  // namespace
106
107 InputMethodPersistence::InputMethodPersistence(
108     InputMethodManager* input_method_manager)
109     : input_method_manager_(input_method_manager),
110       state_(InputMethodManager::STATE_LOGIN_SCREEN) {
111   input_method_manager_->AddObserver(this);
112 }
113
114 InputMethodPersistence::~InputMethodPersistence() {
115   input_method_manager_->RemoveObserver(this);
116 }
117
118 void InputMethodPersistence::InputMethodChanged(
119     InputMethodManager* manager, bool show_message) {
120   DCHECK_EQ(input_method_manager_, manager);
121   const std::string current_input_method =
122       manager->GetCurrentInputMethod().id();
123   // Save the new input method id depending on the current browser state.
124   switch (state_) {
125     case InputMethodManager::STATE_LOGIN_SCREEN:
126       if (!manager->IsLoginKeyboard(current_input_method)) {
127         DVLOG(1) << "Only keyboard layouts are supported: "
128                  << current_input_method;
129         return;
130       }
131       PersistSystemInputMethod(current_input_method);
132       return;
133     case InputMethodManager::STATE_BROWSER_SCREEN:
134       PersistUserInputMethod(current_input_method, manager);
135       return;
136     case InputMethodManager::STATE_LOCK_SCREEN:
137       // We use a special set of input methods on the screen. Do not update.
138       return;
139     case InputMethodManager::STATE_TERMINATING:
140       return;
141   }
142   NOTREACHED();
143 }
144
145 void InputMethodPersistence::OnSessionStateChange(
146     InputMethodManager::State new_state) {
147   state_ = new_state;
148 }
149
150 }  // namespace input_method
151 }  // namespace chromeos