Index: chrome/browser/chromeos/input_method/browser_state_monitor.cc |
diff --git a/chrome/browser/chromeos/input_method/browser_state_monitor.cc b/chrome/browser/chromeos/input_method/browser_state_monitor.cc |
index c2528f1a56600a190cb50da20d755556d99d4c69..8edf28ea56ee6533a3bc2dea27bf01bb83ed7fb5 100644 |
--- a/chrome/browser/chromeos/input_method/browser_state_monitor.cc |
+++ b/chrome/browser/chromeos/input_method/browser_state_monitor.cc |
@@ -45,7 +45,7 @@ BrowserStateMonitor::BrowserStateMonitor(InputMethodManager* manager) |
content::NOTIFICATION_APP_TERMINATING, |
content::NotificationService::AllSources()); |
- // TODO(yusukes): Tell the initial state to the manager. |
+ manager_->SetState(state_); |
manager_->AddObserver(this); |
} |
@@ -53,17 +53,14 @@ BrowserStateMonitor::~BrowserStateMonitor() { |
manager_->RemoveObserver(this); |
} |
+void BrowserStateMonitor::SetPrefServiceForTesting(PrefService* pref_service) { |
+ pref_service_ = pref_service; |
+} |
+ |
void BrowserStateMonitor::UpdateLocalState( |
const std::string& current_input_method) { |
- if (!InputMethodUtil::IsKeyboardLayout(current_input_method)) { |
- LOG(ERROR) << "Only keyboard layouts are supported: " |
- << current_input_method; |
- return; |
- } |
- |
if (!g_browser_process || !g_browser_process->local_state()) |
return; |
- |
g_browser_process->local_state()->SetString( |
language_prefs::kPreferredKeyboardLayout, |
current_input_method); |
@@ -80,22 +77,22 @@ void BrowserStateMonitor::UpdateUserPreferences( |
current_input_method_pref_.SetValue(current_input_method); |
} |
-void BrowserStateMonitor::InputMethodChanged( |
- InputMethodManager* manager, |
- const InputMethodDescriptor& current_input_method, |
- size_t num_active_input_methods) { |
+void BrowserStateMonitor::InputMethodChanged(InputMethodManager* manager) { |
DCHECK_EQ(manager_, manager); |
+ const std::string current_input_method = |
+ manager->GetCurrentInputMethod().id(); |
// Save the new input method id depending on the current browser state. |
switch (state_) { |
case InputMethodManager::STATE_LOGIN_SCREEN: |
- UpdateLocalState(current_input_method.id()); |
+ if (!InputMethodUtil::IsKeyboardLayout(current_input_method)) { |
+ LOG(ERROR) << "Only keyboard layouts are supported: " |
+ << current_input_method; |
+ return; |
+ } |
+ UpdateLocalState(current_input_method); |
return; |
case InputMethodManager::STATE_BROWSER_SCREEN: |
- UpdateUserPreferences(current_input_method.id()); |
- return; |
- case InputMethodManager::STATE_LOGGING_IN: |
- // Do not update the prefs since Preferences::NotifyPrefChanged() will |
- // notify the current/previous input method IDs to the manager. |
+ UpdateUserPreferences(current_input_method); |
return; |
case InputMethodManager::STATE_LOCK_SCREEN: |
// We use a special set of input methods on the screen. Do not update. |
@@ -106,6 +103,9 @@ void BrowserStateMonitor::InputMethodChanged( |
NOTREACHED(); |
} |
+void BrowserStateMonitor::InputMethodPropertyChanged( |
+ InputMethodManager* manager) {} |
+ |
void BrowserStateMonitor::Observe( |
int type, |
const content::NotificationSource& source, |
@@ -118,8 +118,11 @@ void BrowserStateMonitor::Observe( |
case chrome::NOTIFICATION_LOGIN_USER_CHANGED: { |
// The user logged in, but the browser window for user session is not yet |
// ready. An initial input method hasn't been set to the manager. |
- // Note that the notification is also sent when Chrome crashes/restarts. |
- SetState(InputMethodManager::STATE_LOGGING_IN); |
+ // Note that the notification is also sent when Chrome crashes/restarts |
+ // as of writing, but it might be changed in the future (therefore we need |
+ // to listen to NOTIFICATION_SESSION_STARTED as well.) |
+ VLOG(1) << "Received chrome::NOTIFICATION_LOGIN_USER_CHANGED"; |
+ SetState(InputMethodManager::STATE_BROWSER_SCREEN); |
break; |
} |
case chrome::NOTIFICATION_SESSION_STARTED: { |
@@ -128,6 +131,7 @@ void BrowserStateMonitor::Observe( |
// We should NOT call InitializePrefMembers() here since the notification |
// is sent in the PreProfileInit phase in case when Chrome crashes and |
// restarts. |
+ VLOG(1) << "Received chrome::NOTIFICATION_SESSION_STARTED"; |
SetState(InputMethodManager::STATE_BROWSER_SCREEN); |
break; |
} |
@@ -145,33 +149,33 @@ void BrowserStateMonitor::Observe( |
break; |
} |
} |
- |
- // TODO(yusukes): On R20, we should handle Chrome crash/restart correctly. |
- // Currently, a wrong input method could be selected when Chrome crashes and |
- // restarts. |
+ // Note: browser notifications are sent in the following order. |
// |
- // Normal login sequence: |
+ // Normal login: |
// 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. |
// 2. Preferences::NotifyPrefChanged() is called. preload_engines (which |
// might change the current input method) and current/previous input method |
// are sent to the manager. |
// 3. chrome::NOTIFICATION_SESSION_STARTED is sent. |
// |
- // Chrome crash/restart (after logging in) sequence: |
- // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. |
+ // Chrome crash/restart (after logging in): |
+ // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED might be sent. |
// 2. chrome::NOTIFICATION_SESSION_STARTED is sent. |
- // 3. Preferences::NotifyPrefChanged() is called. preload_engines (which |
- // might change the current input method) and current/previous input method |
- // are sent to the manager. When preload_engines are sent to the manager, |
- // UpdateUserPreferences() might be accidentally called. |
+ // 3. Preferences::NotifyPrefChanged() is called. The same things as above |
+ // happen. |
+ // |
+ // We have to be careful not to overwrite both local and user prefs when |
+ // preloaded engine is set. Note that it does not work to do nothing in |
+ // InputMethodChanged() between chrome::NOTIFICATION_LOGIN_USER_CHANGED and |
+ // chrome::NOTIFICATION_SESSION_STARTED because SESSION_STARTED is sent very |
+ // early on Chrome crash/restart. |
} |
void BrowserStateMonitor::SetState(InputMethodManager::State new_state) { |
const InputMethodManager::State old_state = state_; |
state_ = new_state; |
- if (old_state != state_) { |
- // TODO(yusukes): Tell the new state to the manager. |
- } |
+ if (old_state != state_) |
+ manager_->SetState(state_); |
} |
void BrowserStateMonitor::InitializePrefMembers() { |
@@ -179,7 +183,7 @@ void BrowserStateMonitor::InitializePrefMembers() { |
return; |
initialized_ = true; |
- PrefService* pref_service = GetPrefService(); |
+ PrefService* pref_service = pref_service_ ? pref_service_ : GetPrefService(); |
DCHECK(pref_service); |
DCHECK_EQ(InputMethodManager::STATE_BROWSER_SCREEN, state_); |
previous_input_method_pref_.Init( |